쉬방(유닉스)

Shebang (Unix)
#!
쉐방

컴퓨팅에서 shebang스크립트의 선두에 있는 숫자 기호와 느낌표(#!)로 이루어진 문자 시퀀스입니다.그것은 샤프-익스콜레이션, [1][2]샤-방, [3][4]해시방, [5][6]파운드-방 또는 [7]해시-플링이라고도 불린다.

shebang이 있는 텍스트 파일이 Unix와 유사한 운영 체제에서 실행 파일인 것처럼 사용될 때, 프로그램 로더 메커니즘은 파일의 첫 번째 줄의 나머지 부분을 인터프리터 지시로 해석합니다.로더는 지정된 인터프리터 프로그램을 실행하고 스크립트를 실행할 때 처음에 사용되었던 경로를 사용하여 인수로 전달합니다.이렇게 하면 프로그램이 파일을 입력 [8]데이터로 사용할 수 있습니다.예를 들어 스크립트에 경로 경로/대상/스크립트가 지정되어 있고 다음 행으로 시작하는 경우#!/bin/sh프로그램 로더는 첫 번째 인수로 passing path/to/script를 사용하여 /bin/sh 프로그램을 실행하도록 지시됩니다.Linux 에서는 이 동작은 커널 코드와 사용자 공간 코드 [9]양쪽에 기인합니다.

많은 스크립트 언어에서 "#" 문자는 코멘트 마커이기 때문에 쉐방 행은 보통 인터프리터에 의해 무시됩니다.해시 마크를 사용하여 코멘트를 시작하지 않는 일부 언어 인터프리터는 그 [10]목적을 인식하기 위해 쉐방 행을 무시할 수 있습니다.

구문

shebang interpreter 디렉티브의 형식은 다음과 같습니다.[8]

#!filter [옵션]

여기서 인터프리터는 일반적으로 실행 가능한 프로그램에 대한 절대 경로입니다.옵션의 인수는 단일 인수를 나타내는 문자열입니다.#! 뒤의 공백은 옵션입니다.

Linux 에서는 인터프리터에 의해 지정된 파일이 다음 중 하나일 경우 실행할 수 있습니다.

  • 실행 권한과 커널이 직접 실행할 수 있는 코드가 포함되어 있습니다.
  • sysctl을 통해 정의된 래퍼(와인을 사용한 Microsoft .exe 바이너리 실행 등)
  • 셰방

Linux 및 Minix에서는 인터프리터가 스크립트가 될 수도 있습니다.shebang 및 wrapper 체인에서는 검출된 스크립트를 파라미터로 역순으로 취득하는 직접 실행 파일이 생성됩니다.예를 들어 /bin/A 파일이 ELF 형식의 실행 파일인 경우 /bin/B 파일에는 shebang이 포함됩니다.#!/bin/A optparam파일 /bin/C에는 shebang이 포함되어 있습니다.#!/bin/B파일 /bin/C를 실행하면 다음과 같이 해결됩니다./bin/B /bin/C최종적으로 해결되는 것은/bin/A optparam /bin/B /bin/C.

Solaris 및 Darwin에서 파생된 운영 체제(macOS 등)에서는 인터프리터에 의해 지정된 파일은 실행 가능한 바이너리여야 하며 스크립트 [11]자체일 수 없습니다.

일반적인 쉐방 라인:

  • #!/bin/shBourne 쉘 또는 /bin 디렉토리에 있다고 가정한 호환 셸을 사용하여 파일을 실행합니다.
  • #!/bin/bashBash 쉘을 사용하여 파일 실행
  • #!/usr/bin/pwsh– PowerShell을 사용하여 파일 실행
  • #!/usr/bin/env python3– Python 인터프리터를 사용하여 env 프로그램 검색 경로를 사용하여 실행
  • #!/bin/false– 아무것도 하지 않고 0이 아닌 종료 상태를 반환하여 장애를 나타냅니다.특정 컨텍스트에서의 실행을 목적으로 하는 스크립트파일의 스탠드아론 실행을 방지하기 위해 사용됩니다..sh/module 명령어,sourcecsh/tcsh, 또는 .profile, .cshrc 또는 .disc 파일로 지정합니다.

Shebang 행에는 인터프리터에 전달되는 특정 옵션이 포함될 수 있습니다.다만, 실장은 옵션의 해석 동작에 따라 다릅니다.포터빌리티를 실현하기 위해서는, 공백이 짜넣어져 있지 않은 옵션을 1개만 지정할 필요가 있습니다.휴대성에 관한 기타 가이드라인은 다음과 같습니다.

목적

인터프리터 디렉티브를 사용하면 스크립트와 데이터 파일을 명령어로 사용할 수 있습니다.커맨드라인에서 인터프리터를 사용하여 스크립트를 프리픽스할 필요가 없어지기 때문에 사용자나 다른 프로그램으로부터 실장의 상세를 숨길 수 있습니다.

경로 some/path/to/foo에 의해 식별되는 Bourne 쉘 스크립트에 첫 번째 행이 있습니다.

#!/bin/sh -x

파라미터 바 및 baz를 사용하여 실행됩니다.

썸/패스/푸 바 바즈

는 다음 명령줄을 실제로 실행한 경우와 같은 결과를 제공합니다.

/bin/sh -x some/path/to/foo bar baz

/bin/shBourne 쉘을 지정하면 최종 결과는 파일 some/path/to/foo 내의 모든 셸 명령어가 각각 bar와 baz를 갖는 위치 변수 $1$2와 함께 실행됩니다.또한 첫 번째 숫자 기호는 Bourne 쉘 언어(및 다른 많은 통역자가 이해하는 언어)의 코멘트를 도입하기 위해 사용되는 문자이기 때문에 shebang 행 전체가 통역자에 의해 무시됩니다.

단, shebang 회선을 무시하는 것은 인터프리터에 달려 있습니다.따라서 다음 2행으로 구성된 스크립트는 실행 시 두 행을 모두 표준 출력으로 에코합니다.

#!/bin/cat Hello world! 

파일 확장자와 인터프리터 어플리케이션 간의 글로벌어소시에이션목록을 사용하는 경우와 비교하여 인터프리터 디렉티브 방식에서는 글로벌시스템레벨에서 알 수 없는 인터프리터를 사용할 수 있습니다.관리자 권한도 없습니다.또한 파일 확장자 이름 공간을 오버로드하지 않고 특정 인터프리터를 선택할 수 있으며(1개의 파일 확장자가 여러 개의 파일 형식을 참조), 다른 프로그램에 의해 호출 구문을 변경하지 않고 스크립트의 구현 언어를 변경할 수 있습니다.스크립트 호출자는 스크립트 자체가 사용할 인터프리터를 지정하는 역할을 하기 때문에 구현 언어를 알 필요가 없습니다.

휴대성

프로그램 위치

Shebang은 시스템 실행 파일에 대한 절대 경로(또는 현재 작업 디렉토리에 대한 상대 경로)를 지정해야 합니다.이렇게 하면 비표준 파일시스템 레이아웃을 가진 시스템에서 문제가 발생할 수 있습니다.시스템이 상당히 표준적인 경로를 가지고 있는 경우에도 동일한 운영체제의 변형체제가 원하는 인터프리터의 위치가 다를 수 있습니다.를 들어 Python은 /usr/bin/python3, /usr/local/bin/python3 또는 일반 사용자에 의해 설치된 경우 /home/username/bin/python3과 같은 위치에 있을 수 있습니다.

POSIX 쉘에서도 같은 문제가 발생합니다.이는 POSIX가 이름을 sh로 해야 할 뿐 경로를 의무화하지는 않았기 때문입니다.일반적인 값은 /bin/sh이지만 Solaris 등의 일부 시스템에서는 /usr/xpg4/bin/[12]sh에 POSIX 호환 셸이 있습니다.많은 Linux 시스템에서 /bin/sh는 Bourne Again 쉘(BASH)인 /bin/bash에 대한 하드 또는 심볼 링크입니다.sh를 가리키는 shebang을 유지하면서 bash 고유의 구문을 사용하는 것도 [13]portable이 아닙니다.

이 때문에, 스크립트를 1대의 컴퓨터에서 다른 컴퓨터로 카피한 후, shebang 행을 편집할 필요가 있는 경우가 있습니다.이는 스크립트에 코드화된 경로가 과거 인터프리터 배치의 일관성에 따라 새로운 머신에 적용되지 않을 수 있기 때문입니다.이러한 이유로 POSIX는 패스명을 표준화하지 않기 때문[14]POSIX는 기능을 표준화하지 않습니다.GNU Autoconf 도구는 매크로 AC_를 사용하여 시스템 지원을 테스트할 수 있습니다.SYS_INTERPRETER.[15]

대부분의 경우 /usr/bin/env 프로그램을 사용하여 간접 수준을 도입함으로써 이 제한을 회피할 수 있습니다. #!다음 예시와 같이 /usr/bin/env 뒤에 원하는 명령어가 계속됩니다.

#!/usr/bin/env sh

이것은 주로 /usr/bin/env 경로가 env 유틸리티에 일반적으로 사용되며 사용자의 $PATH에서 발견된 첫 번째 sh(일반적으로 /bin/sh)를 호출하기 때문에 작동합니다.

OpenServer 5.0.6 및 Unicos 9.0.2에서는 /bin/env만 있고 /usr/bin/env는 없는 휴대성 문제가 있습니다.

문자 해석

또 하나의 이식성 문제는 명령어 인수의 해석입니다.Linux 등의 일부 시스템에서는 [16]인수를 분할하지 않습니다.예를 들어 첫 번째 행에서 스크립트를 실행할 때 다음과 같이 됩니다.

#!/usr/bin/env python3 -c

첫 번째 공백 뒤의 모든 텍스트는 단일 인수로 취급됩니다.python3 -c두 개의 인수가 아닌 하나의 인수로 /usr/bin/env에 전달됩니다.Cygwin도 이런 식으로 행동합니다.

추가 래퍼를 사용하면 복잡한 인터프리터 호출이 가능합니다.FreeBSD 6.0(2005)에서는 shebang reading 동작을 non-spliting으로 변경함으로써 -S 옵션이 env에 도입되었습니다.이 옵션은 [17]env에게 문자열 자체를 분할하도록 지시합니다.coreutils 8.30 (2018) 이후 GNU env 유틸리티에도 이 [18]기능이 포함되어 있습니다.이 옵션을 사용하면 분할로 인한 커널 엔드의 이식성 문제가 완화되지만 env가 특정 확장을 지원하는 요건이 추가됩니다.

또 다른 문제는 shebang 회선 직후캐리지 리턴 문자가 포함된 스크립트입니다.이것은 Microsoft Windows 등 DOS 회선 분리를 사용하는 시스템에서 편집된 결과일 수 있습니다.일부 시스템에서는 캐리지 리턴 문자를 인터프리터 명령의 일부로 해석하여 오류 [19]메시지가 나타납니다.

매직 넘버

shebang은 실제로 실행 파일 내의 매직 번호의 사람이 읽을 수 있는 인스턴스입니다.매직 바이트 문자열은 0x23 0x21 이며 ASCII의 2글자 인코딩은 #! 입니다.이 매직 번호는 파일이 스크립트인지 실행 가능한 이진수인지 결정하는 "exec" 함수 패밀리에 의해 탐지됩니다.shebang이 있으면 지정된 실행 파일(일반적으로 스크립트 언어 인터프리터)이 실행됩니다.UNIX의 일부 구버전은 일반 셰방 뒤에 공백과 슬래시()#! /가 붙을 것으로 예상하지만[20] 이는 사실이 [21]아닌 것으로 보인다. 오히려 셰방 뒤에 공백이 있는 것은 전통적으로 허용되어 왔고 때로는 공백으로 기록되기도 했다(아래[citation needed]1980년 이메일 섹션 참조).

셰방 문자는 UTF-8을 포함한 확장 ASCII 인코딩에서 동일한2 바이트로 표시됩니다.UTF-8은 현재 Unix와 유사한 시스템에서 스크립트 및 기타 텍스트파일에 일반적으로 사용됩니다.단, UTF-8 파일은 옵션의 바이트 순서 마크(BOM)로 시작할 수 있습니다.exec 함수가 바이트 0x230x21을 검출하는 경우 shebang 전에 BOM(0xEF 0xBB 0xBF)이 존재하면 스크립트인터프리터가 실행되지 않습니다.일부 당국에서는 이러한 이유와 광범위한 상호 운용성 및 철학적 우려 때문에 POSIX([22]Unix-like) 스크립트에서 바이트 순서 마크를 사용하지 말 것을 권장합니다.또한 UTF-8에서는 바이트 순서 마크가 필요하지 않습니다.이 부호화에는 엔디안니스 문제가 없기 때문입니다.UTF-8 [citation needed]로서 부호화를 식별하는 데만 사용됩니다.

어원

인터프리터 디렉티브로 시작하는 실행 파일은 스크립트라고 불리며, 종종 의도된 인터프리터의 이름 또는 일반적인 분류가 선행됩니다.고유 2개의 문자를 나타내는 shebang이라는 이름SHArp bang 또는 haSH bang의 부정확한 축음에서 유래한 것으로 생각되며, 이들 문자의 일반적인 2개의 Unix 이름을 가리킵니다.shebangsh에 대한 또 다른 이론은 shebang이 [23]보통 shebang과 함께 호출되는 기본 셸 sh에서 비롯되었다는 것입니다.이 사용법은 1989년 [24]12월까지 사용되었으며 아마도 그 이전일 것입니다.

역사

이 셰방은 벨 연구소에서 7번과 8번 사이에 데니스 리치에 의해 소개되었다.Berkeley의 Computer Science Research의 BSD 릴리즈에도 추가되었습니다(현재는 2.8).디폴트로는[25] 4.2BSD에 의해 활성화 됩니다).AT&T Bell Laboratories Edition 8 Unix 이후 에디션은 일반에 공개되지 않았기 때문에 이 기능이 처음으로 널리 알려진 것은 BSD입니다.

통역사 지시가 부족하지만 셸 스크립트에 대한 지원, 7유닉스 1979,[26]에서 그 대신":"얼마나 자주'o'를 같이들 사용 권한과 파일 그 조개에 의해 처리될 것은 본 껍질의(가끔은 대본에 초기 캐릭터에 따라 한 시설에 대해 묘사한 설명서에 분명하다r"#") 파일에 포함된 명령어를 해석하고 실행하는 서브셸을 생성합니다.이 모델에서 스크립트는 Bourne 쉘 내에서 호출된 경우에만 다른 명령어와 동일하게 동작합니다.운영체제 자체의 exec() 시스템트랩을 통해 이러한 파일을 직접 실행하려고 하면 실패하고 스크립트가 일반적인 시스템명령어와 동일하게 동작하지 않게 됩니다.

이후 버전의 Unix 유사 시스템에서는 이 불일치가 해소되었습니다.Dennis Ritchie는 1980년 1월에 버전 8 Unix에 대한 인터프리터 디렉티브에 대한 커널 지원을 다음과 같이 발표했습니다.[25]

from uucp Thu Jan 10 01:37:58 1980 > From dmr Thu Jan 10 04:25:49 remote from the research The system은 파일이 매직 문자 #!로 시작되는 경우 행의 나머지 부분은 실행된 파일의 인터프리터 이름으로 인식되도록 변경되었습니다.이전에는 (그리고 지금도) 셸이 이 작업의 대부분을 수행했습니다.텍스트 파일의 이름을 명령어로 입력하면 자동으로 실행 가능 모드로 텍스트 파일에서 실행됩니다.이 설비를 시스템에 도입하면 다음과 같은 이점이 있습니다.1) 셸 스크립트는 'exec'의 대상이 될 수 있기 때문에 실제 실행 가능 파일과 비슷합니다. 2) 이러한 명령어가 실행 중일 때 'ps'를 실행하면 'sh'가 아닌 실제 이름이 표시됩니다.마찬가지로 회계는 실명을 기준으로 이루어집니다.3) 셸 스크립트는 set-user-ID[a]할 수 있습니다.4) 대체 셸을 사용할 수 있는 것이 더 간단합니다.예를 들어 Berkeley csh를 좋아하는 경우 파일을 해석하는 셸에 대해서는 질문이 없습니다.5) 다른 통역사가 보다 원활하게 적응할 수 있도록 합니다.이 훌륭한 기회를 이용하려면 셸 스크립트의 첫 번째 줄 왼쪽 여백에 #! /bin/sh를 넣으십시오.! 뒤의 공백도 괜찮습니다.완전한 패스명을 사용합니다(검색은 이루어지지 않습니다).현재 전체 행이 16자로 제한되지만 이 제한은 높아집니다. 

그러나 기능의 작성자는 이름을 지정하지 않았습니다.[28]

출처: "Ritchie, Dennis M (Dennis)** CTR **" <dmr@[redacted]>수신인: <[redacted]@talisman.org> 날짜: 2009년 11월 19일 (목) 18:37:37 - 0600 제목 : RE : What do - your - call # !< something > line ?우리가 제대로 된 이름을 지어준 적이 있는지 기억이 안 나요.꽤 늦게 도입되었습니다.버클리 Unix에서 열린 UCB 컨퍼런스에서 아이디어를 얻은 것 같습니다.처음 설치했을지도 모르지만 다른 곳에서 얻은 아이디어입니다.이름은 해시방 같은 영국풍이라고 할 수 있을 것 같습니다만, 어쨌든 애칭을 사용한 것은 기억나지 않습니다. 

인터프리터 디렉티브에 대한 커널 지원은 다른 버전의 Unix로 확대되어 있으며, 하나의 최신 구현은 fs/binfmt_script.[29]c의 Linux 커널 소스에서 확인할 수 있습니다.

이 메커니즘에 의해 스크립트는 일반 컴파일된 프로그램이 풀시스템 프로그램이나 다른 스크립트의 인터프리터로서도 사용할 수 있는 거의 모든 컨텍스트에서 사용할 수 있습니다.단, 일부 초기 버전의 커널 지원에서는 인터프리터 디렉티브의 길이가 약 32자(첫 번째 구현에서는 16자)로 제한되거나 인터프리터 이름이 디렉티브의 파라미터에서 분할되지 않거나 기타 기호가 발생합니다.또한 일부 최신 시스템에서는 보안을 위해 메커니즘 전체를 제한하거나 비활성화할 수 있습니다(예를 들어 많은 시스템에서 스크립트에 대해 set-user-id 지원이 비활성화되어 있습니다).

#! 매직넘버에 대한 완전한 커널을 지원하는 시스템에서도 인터프리터 디렉티브가 없는 스크립트(보통 실행 권한이 필요하지만)는 Bourne 쉘의 레거시 스크립트 처리에 의해 여전히 실행 가능한 스크립트가 많다는 점에 유의하십시오.그런 다음 스크립트는 사용자의 기본 셸에 의해 해석됩니다.

「 」를 참조해 주세요.

메모들

  1. ^ setuid 기능은 처리 중에 스크립트를 변경하는 [27]레이스 조건을 이용할 수 있다는 것을 깨달은 후 대부분의 최신 운영 체제에서 사용할 수 없습니다.

레퍼런스

  1. ^ "Advanced Bash Scripting Guide: Chapter 2. Starting Off With a Sha-Bang". Archived from the original on 10 December 2019. Retrieved 10 December 2019.
  2. ^ Cooper, Mendel (5 November 2010). Advanced Bash Scripting Guide 5.3 Volume 1. lulu.com. p. 5. ISBN 978-1-4357-5218-4.
  3. ^ MacDonald, Matthew (2011). HTML5: The Missing Manual. Sebastopol, California: O'Reilly Media. p. 373. ISBN 978-1-4493-0239-9.
  4. ^ Lutz, Mark (September 2009). Learning Python (4th ed.). O'Reilly Media. p. 48. ISBN 978-0-596-15806-4.
  5. ^ Guelich, Gundavaram and Birznieks, Scott, Shishir and Gunther (29 July 2000). CGI Programming with PERL (2nd ed.). O'Reilly Media. p. 358. ISBN 978-1-56592-419-2.
  6. ^ Lie Hetland, Magnus (4 October 2005). Beginning Python: From Novice to Professional. Apress. p. 21. ISBN 978-1-59059-519-0.
  7. ^ Schitka, John (24 December 2002). Linux+ Guide to Linux Certification. Course Technology. p. 353. ISBN 978-0-619-13004-6.
  8. ^ a b "execve(2) - Linux man page". Retrieved 21 October 2010.
  9. ^ Corbet, Jonathan. "The case of the supersized shebang". LWN.net.
  10. ^ "SRFI 22".
  11. ^ "Python - Python3 shebang line not working as expected".
  12. ^ "The Open Group Base Specifications Issue 7". 2008. Retrieved 5 April 2010.
  13. ^ "pixelbeat.org: Common shell script mistakes". It's much better to test scripts directly in a POSIX compliant shell if possible. The `bash --posix` option doesn't suffice as it still accepts some 'bashisms'
  14. ^ "Chapter 2. Shell Command Language", The Open Group Base Specifications (IEEE Std 1003.1-2017) (Issue 7 ed.), IEEE, 2018 [2008], If the first line of a file of shell commands starts with the characters "#!", the results are unspecified.
  15. ^ Autoconf, Free Software Foundation, Macro: AC_SYS_INTERPRETER: Check whether the system supports starting scripts with a line of the form ‘#!/bin/sh’ to select the interpreter to use for the script.
  16. ^ "/usr/bin/env behaviour". Mail-index.netbsd.org. 9 November 2008. Retrieved 18 November 2010.
  17. ^ env(1)FreeBSD 일반 명령어 매뉴얼
  18. ^ "env invocation". GNU Coreutils. Retrieved 11 February 2020.
  19. ^ "Carriage Return causes bash to fail". 8 November 2013.
  20. ^ "GNU Autoconf Manual v2.57, Chapter 10: Portable Shell Programming". Archived from the original on 18 January 2008. Retrieved 14 May 2020.
  21. ^ "The #! magic, details about the shebang/hash-bang mechanism on various Unix flavours". Retrieved 14 May 2020.
  22. ^ "FAQ - UTF-8, UTF-16, UTF-32 & BOM: Can a UTF-8 data stream contain the BOM character (in UTF-8 form)? If yes, then can I still assume the remaining UTF-8 bytes are in big-endian order?". Retrieved 4 January 2009.
  23. ^ "Jargon File entry for shebang". Catb.org. Retrieved 16 June 2010.
  24. ^ Wall, Larry. "Perl didn't grok setuid scripts that had a space on the first line between the shebang and the interpreter name". USENET.
  25. ^ a b "CSRG Archive CD-ROMs".
  26. ^ UNIX TIME-SHARING SYSTEM: UNIX PROGRAMMER'S MANUAL (PDF), vol. 2A (Seventh ed.), January 1979
  27. ^ Gilles. "linux - Why is SUID disabled for shell scripts but not for binaries?". Information Security Stack Exchange.
  28. ^ Richie, Dennis. "Dennis Ritchie and Hash-Bang". Talisman.org. Retrieved 3 December 2020.
  29. ^ Rubini, Alessandro (31 December 1997). "Playing with Binary Formats". Linux Journal. Retrieved 1 January 2015.

외부 링크