.sh 확장자를 지정 하시겠습니까?


12

왜 일부 시스템은 .sh확장자없이 파일 이름을 지정하여 파일 을 실행 하고 다른 시스템은 이름과 확장자를 요구합니까? 내 경우에는이 지침에 따라 일련의 명령을 작성하려고합니다 .

지금 확장을 지정하고 있지만 명령을 실행할 수없는 .sh것이 좋습니다.


4
.sh확장으로 사용 하는 것은 많은 상황에서 나쁜 습관으로 간주됩니다. 다른 명령의 이름을 지정하는 방법과 달리 (실행하지 않음 ls.elf) 종종 오해의 소지가 있습니다 (로 foo.sh시작 하면 실행하면 빌드 된 것과 다른 해석기 #!/bin/bash로 실행 sh foo.sh됩니다) ), foo.sh파이썬 프로그램으로 다시 작성 하는 경우 해당 확장명을 사용하면 현재 오해의 소지가있는 이름을 유지하고 해당 프로그램을 호출하는 모든 프로그램을 다시 작성해야합니다.
Charles Duffy

2
...이 곳 입니다 하지와 명령, 가장 좋은 방법은 쉘 라이브러리입니다 +x세트 - foo.sh모든 POSIX 쉘에 공급 될 수있는 라이브러리입니다 foo.bash, 배쉬로 공급 될 수 foo.ksh등 KSH로
찰스 더피

답변:


39

당신은 혼란스러워합니다. .sh확장은 인간에게 힌트이며, 시스템 파일을 처리하는 방법에 전혀 영향을주지 않습니다. 유닉스 / 리눅스는 윈도우의 Secrets.pdf.exe실수를 하지 않았다 .

여기에 입력시 실행되는 사항입니다 foo:

  1. 리디렉션 STDIN, STDOUT그리고이 STDERR설정됩니다.

  2. 쉘은 내부 해시 테이블을 검사하여에 대한 $PATH항목을 이미 알고 있는지 확인합니다 foo. 존재하지 않는 경우, 쉘은에서 디렉토리를 검색하여 파일 사용 권한에 실행 비트가 설정된 $PATH파일을 찾습니다 foo. 첫 foo승리.

  3. 파일의 처음 2 바이트 foo#!인 경우 다음 문자열은 실행할 인터프리터의 이름입니다. 따라서 #!/bin/bashBash 스크립트, #!/usr/bin/perlPerl 스크립트 등을 소개합니다.

  4. 파일이로 시작 \177ELF하면 이진 실행 파일이며 ld.so시작됩니다.

읽기 man execveman ld.so더 자세한 설명.


15
예, 리눅스에 당신은 실제로 실행 있다는 이름에서 단서와 Secrets.pdf을 더블 클릭 수)
OrangeDog

1
@OrangeDog 농담을 알고 있지만 실행 비트 ( chmod +x)가 거의 이것을 해결 한다고 지적해야한다고 생각 합니까?
wchargin

3
@WChargin 파일 시스템의 작동 방식 (예 : 마운트 된 네트워크 공유 또는 NTFS 파티션이 x모든 것에 비트를 낙관적으로 설정할 수 있음 )과 파일의 출처 (디렉토리를 제어하는 ​​모든 프로세스가 권한 설정에 속일 수 있음)에 따라 다릅니다. . 따라서 그것을 완화 시키지만 해결 한다고 말할 수 없습니다 .
IMSoP

2
@WChargin, 그러나 나는 보통 파일 관리자가 실행 가능한 비트를 보여주지 않는다고 생각한다.
Paul Draper

1
나는 Secrets.pdf.exe바보 같은 hide file extension기능을 항상 비활성화하기 때문에 실수로 클릭하지 않습니다
phuclv

12

핵심은 이것입니다 : 확장자는 유닉스 계열 시스템 시스템과 무관합니다. 파일 이름은 단지 이름이며 스크립트 또는 컴파일 된 실행 파일의 실행 여부에 영향을 미치지 않습니다 . 프로그래머는 .sh파일이 셸 스크립트 또는 .py파이썬 스크립트 임을 나타내는 확장을 추가 할 수 있지만 Windows와 달리 유닉스는 이름 지정에 관심이 없으며 권한에 관심이 있습니다.

중요한 것은 파일에 부여 된 실행 권한입니다. 확인할 수있는

ls -l /path/to/file

실행 파일 실행

스크립트를 실행하려면 일반적으로 몇 가지 방법이 있습니다.

  • 현재 디렉토리가 스크립트와 동일하고 스크립트에 실행 권한이 있으면 다음과 같이 실행할 수 있습니다 ./my_script_name. 은 .현재 디렉토리를 의미합니다.
  • 현재 디렉토리가 다르고 스크립트에 실행 권한이있는 경우 전체 경로를 지정하여 실행할 수 있습니다. /home/user/bin/my_script_name

(위의 두 가지 방법이 실행 권한 집합을 가지고에 의존하고, 파일의 일부인지 여부 $PATH변수가 무관의 존재. #!라인은 또한 중요한, 그것은,이 스크립트가 현재 쉘에 의해 실행됩니다없이 열려있는 내가 가지고있는 경우. csh스크립트를 그 줄이 없으면을 사용하여 bash에서 실행하려고 ./my_script.csh하면 실패합니다)

  • 스크립트가 $PATH변수의 일부인 디렉토리에있는 경우 이름을 호출하여 실행할 수 있습니다. 폴더에 chmod있기 때문에 이름을 입력하기 만하면 명령 줄에서 command를 호출 할 수 있습니다 /bin. /bin항상 $PATH변수의 일부입니다 . 이 경우 스크립트 권한의 실행 권한 및 위치
  • 명령으로 인터프리터를 지정하고 인수로 스크립트를 지정하십시오. 그렇게하면 스크립트가 인터프리터에게 입력 파일로 사용됩니다.
  • 파일 소싱. . filename.sh또는 source filename.sh직접적 명령 줄에 입력 된 것처럼이 키보드 입력, 즉 것처럼 스크립트를 처리 할 것입니다. 이 경우 실행 권한과 위치는 중요하지 않습니다

권한을 실행하기 위해 인터프리터와 함께 실행되는 예제 # 1

$-> ls -l abc.py                                                               
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py                                                              
a
b
c

./실행 가능 권한 세트 인 shebang 행 세트 로 실행 중인 예 # 2 .

$-> cat abc.py                                                                 
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
   print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py                                                                   
a
b
c

예제 # 3, shebang 라인 세트없이 실행 (bash는 파이썬 스크립트를 읽을 수 없기 때문에 실패합니다. shebang 라인은 현재 쉘을 인터프리터로 가정하지 않습니다)

$-> cat abc.py                                                                 
for letter in 'a' 'b' 'c' :
   print letter
$-> ./abc.py                                                                   
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")

예제 # 4, $PATH변수의 일부인 실행 권한이 설정된 양식 폴더가있는 스크립트 실행

#  /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh

$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.                    
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py          
$-> # after adding the line with vi text editor, we can run
$-> abc.py                                                                     
a
b
c

확장은 중요하지 않기 때문에 확장을 제거하는 예제 # 5는 여전히 실행되지만 권한이 있으며 다음의 일부입니다 $PATH.

$-> mv ~/bin/abc.py  ~/bin/abc                                                 
$-> abc
a
b
c

나는 명령을 실행 하고이 '-rwxr-x ---'를 얻습니다. 값을 읽고 싶은데 어떻게 변경할 수 있습니까?
Philip Kirkbride

아니면 단순히 'filename.sh'의 이름을 'filename'으로 바꾸어야한다고 말씀하십니까?
Philip Kirkbride

1
@PhilipKirkbride 이름은 관련이 없습니다. 명령을 어떻게 실행합니까? 어 is 어? 디렉토리가 당신의 일부 PATH입니까?
Sergiy Kolodyazhnyy

@PhilipKirkbride 답변을 더 명확하게 만들기 위해 잠시 후에 답변을 확장하겠습니다.
Sergiy Kolodyazhnyy

1
man chmod권한 설정 방법을 살펴보십시오.
Nick Mertin

6

여기에 좋은 설명이 있습니다. 방금 실행 파일에 파일 확장자를 사용해서는 안된다는 것을 이상적으로 추가하고 싶었습니다.

일반적으로 비교적 쉬운 작업을 수행해야하며 작은 셸 스크립트로 시작합니다. 시간이 지남에 따라 스크립트에 유지 관리 할 수 ​​없게 될 때까지 또는 쉘 스크립트로는 쉽게 달성 할 수없는 기능이 필요할 때까지 더 많은 기능을 스크립트에 추가하기 시작합니다. , perl, ...?).

처음부터 다시 쓰는 것은 일반적으로 오류로 간주되지만 스크립트의 경우 일반적으로 크지 않거나 기능이 많지 않기 때문에 의미가 있습니다. 그러나 초기 셸 스크립트의 기능과 매개 변수 / 플래그를 유지하면서 다른 언어로 처음부터 다시 작성하는 것이 가능하다고 가정합시다.

이 스크립트의 사용자는이 언어 변경에 대해 알 필요가 없으며 동일한 명령을 계속 실행하며 계속 작동합니다.

스크립트의 이름이 do-something.sh이면 계속 될 수 do-something.sh있지만 이제는 Python으로 작성되므로 초기 힌트 는 완전히 잘못된 것입니다.


4

확장명없이 파일을 실행하려면 많은 것을 할 필요가 없습니다. 첫 번째 줄에 bash 스크립트의 경우 적절한 shebang 줄이 있는지 확인하십시오.

#!/bin/bash

그런 다음 파일을 시스템에서 실행 가능하게 만들어야합니다.

chmod 755 yourfilename

chmod +x yourfilename숫자를 쉽게 설명 하는 것과 같습니다 .

그것은 추가 된 8 진수의 트리플 숫자, 첫 번째 숫자는 더 많이 찾을 수에, 사용자, 그룹의 두 번째, 및 다른 사람을위한 세 번째의 약자입니다 여기 .

그리고 스크립트와 같은 디렉토리에 있다면 다음 ./과 같이 사용하는 것을 잊지 마십시오 .

./yourfilename

이것을 시도했다. 불행히도 원래 결과와 차이가 없습니다.
Philip Kirkbride

@PhilipKirkbride는 내 수정 된 답변을 보았을 것입니다. 이것은 아마도 더 많은 빛을 비출 것입니다.
Videonauth

0

.sh 접미사는 실제로 방해가 될 수 있습니다. 왜냐하면 그것을 실행하려면 작동하지 않는 myscript 대신 myscript.sh를 입력해야하기 때문입니다. .sh 접미사없이 "myscript"라고 부르는 것이 좋으며, "file"명령을 빠르게 사용하면 바이너리 실행 파일 (Linux의 경우 ELF 형식) 또는 쉘 스크립트인지 또는 다른 종류의 스크립트인지를 알 수 있습니다.

QDOS (미로 소프트가 불법 복제 한 후 불법적으로 판매 한 후 IBM에서 "Quick and Dirty Operating System, 나중에"DOS "로 이름을 바꿨 음) 및 Windows를 포함한 기타 저렴한 CP / M 리핑은 이러한 시스템에 없습니다. 파일에 대한 실행 권한과 같은 것. 이로 인해 지난 30-40 년 동안 수많은 보안 문제가 발생했습니다. 실제로 몇 분 전에 방금 zip 파일 이름이 MYPICTURE.JPG.zip으로 변경된 zip 파일이 여러 정크 메일을 받았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.