“/ bin / sh”가“/ bin / bash”를 가리킬 때 쉘 스크립트 실행


11

질문 에서 다음을 읽었습니다 .

bash는 --posix 스위치를 지원하므로 POSIX와 호환됩니다. 또한 sh로 호출 된 경우 POSIX를 모방하려고 시도합니다 .

위의 인용문 /bin/sh은이 링크가 가리키는 링크라고 가정합니다 /bin/bash.

그러나 "sh로 호출"의 의미를 이해하지 못합니다 .


"script.sh"라는 다음 스크립트가 있다고 가정하십시오.

#!/bin/bash
echo "Hello World"

스크립트가 일반 bash모드 에서 실행되는지 POSIX 모드에서 실행되는지 다음 각 경우에 알려주십시오 (실행중인 터미널에서 다음 명령을 실행했다고 가정 bash).

  1. sh script.sh
  2. bash script.sh
  3. ./script.sh

이제 "script.sh"(위의 스크립트와 유사하지만 shebang이없는)라는 다음 스크립트가 있다고 가정하십시오.

echo "Hello World"

스크립트가 일반 bash모드 에서 실행되는지 POSIX 모드에서 실행되는지 다음 각 경우에 알려주십시오 (실행중인 터미널에서 다음 명령을 실행했다고 가정 bash).

  1. sh script2.sh
  2. bash script2.sh
  3. ./script2.sh

답변:


19

사례 1과 4 만 POSIX 모드에서 실행됩니다 ( shsh를 구현하지 않고 bash 라고 가정 ). shebang에서 여부에 관계 bash없이 명시 적으로 없이 호출하는 경우 --posix는 그렇지 않습니다. 어떤 경우는 명시 적으로 호출하는 sh것입니다. shebang은 이미 스크립트에 대해 명시 적으로 쉘이 시작되지 않은 경우에만 사용됩니다.

Case 6은 터미널이 실행 중이 bash면 POSIX 모드에서 실행되지 않으며 Bash는 자체를 사용하여 호출합니다. 터미널 대신 zsh을 실행 한 경우, 경우 6 또한 POSIX 모드에서 실행됩니다. POSIX는이 경우 정확히 어떤 일이 발생해야하는지 모호 하며 Bash와 zsh는 다른 선택을했습니다. Bash는 자체를 사용하여 스크립트를 호출하고 zsh는 sh(어떤 것이 든 사용 ) 사용합니다. 다른 껍질도 그 시점에 따라 다릅니다.


어떤 모드인지 알려주는 간단한 방법 중 하나는 스크립트 본문을 만드는 것입니다.

kill -SIGHUP

이는 것 POSIX 모드에서 오류와 함께 실패 ,하지만에 대한 사용 지침을 제공 kill그것의 외부. 이것은 쉬운 구별이며 발생할 가능성이있는 한 Bash 버전의 긴 범위를 통해 작동합니다.


3
환경 변수 bash또는와 같은 POSIX 모드에서 강제 로 실행 되는 다른 것들이 있습니다 . POSIXLY_CORRECTSHELLOPTS=posix
Stéphane Chazelas

1
[ -o posix ]bash에서 posix 모드로 실행 중인지 확인하는 더 확실한 방법입니다 (yash를 제외하고 다른 쉘에서는 아님 sh). 스크립트 에서 그렇게하고 싶지 않습니다 . POSIXLY_CORRECT=1 bash -c '[ -o posix ] && echo yes'출력 yes`
스테판 Chazelas가

2
6의 경우, bash는 POSIX가 요구하는대로 POSIX 모드에 있을 때 POSIX 모드로 스크립트를 호출 합니다. POSIX는 she-bang 메커니즘을 지정하지 않으며 6은 실행 가능한 스크립트를 갖는 유일한 POSIX 방법이며 명확하게 지정됩니다 (POSIX 환경에서 스크립트는 호환되는 sh 유틸리티에 의해 해석됩니다).
Stéphane Chazelas

8

"invoked as"는 Bash를 시작하는 프로세스가 "zeroth"명령 행 인수에 넣는 모든 것을 가리 킵니다 argv[0].

프로그램이 exec*()syscalls 로 시작되면 실제로 프로그램을 포함하는 이진 파일의 이름을 알지 못하지만 대신 호출 프로세스는 원하는 것을 자유롭게 넣을 수 있습니다. 일반적으로 이름은 파일 시스템에서 /bin/sh가져 오므로을 실행하면 그 이름 이 표시됩니다. 그리고 /bin/shBash 라면 심볼릭 링크 일 필요는 없으며 하드 링크이거나 쉘 프로그램의 다른 사본 일 수 있습니다.

"프로그램 이름"설정의 예로, Bash의 exec명령은 -a옵션으로 0 번째 인수를 설정할 수 있습니다 . (우리는 Perl이나 C 등으로 직접 똑같이 할 수 있습니다.)

다음 myname은 간단한 C 프로그램으로, 0 번째 인수 인 자체 이름을 출력합니다.

$ ./myname 
I am ./myname
$ (exec -a something ./myname )
I am something
$ mv ./myname somename
$ ln -s somename othername
$ ./somename 
I am ./somename
$ ./othername
I am ./othername

출처:

#include <stdio.h>
int main(int argc, char *argv[]) {
    printf("I am %s\n", argv[0]);
    return 0;
}

그러나 번호가 매겨진 질문에 대답하려면 ...

(1 & 4) running 은에 있을지 모르지만 아마도 같은 것을sh somescript 실행 sh합니다 .PATH/bin/sh/usr/xpg4/bin/sh

  • Bash 인 경우 이름이 보이기 때문에 POSIX 모드에서 실행됩니다 sh.
  • Z 쉘 또는 Korn 쉘인 경우에도 마찬가지로 이름 sh이 표시되지만 "SH 호환"모드에서 실행됩니다.이 모드는 Bourne 쉘 호환을 목표로하며이 두 쉘에서 전체 POSIX 호환 모드와 미묘하게 다릅니다. .
  • Almquist 쉘, 실제 Bourne 쉘 또는 다른 것 일 수 있습니다.

(2 & 5) 러닝 bash somescript은 일반 배쉬 모드에서 실행 됩니다 (물론 그것은 bash당신의 PATH것이 무엇인지 에 달려 있습니다 .)

(3) 여기서 스크립트 이름은 프로그램 파일 대신 시스템 호출에 직접 제공됩니다. 커널은 hashbang 행을 읽고이를 사용하여 스크립트를 실행합니다.

(6) 이것은 복잡한 것입니다. (3)과 비슷하지만 ENOEXEC (Exec format error)해시 뱅 라인이 없기 때문에 프로그램 시작을위한 시스템 호출이 실패합니다 ( ). 다음에 무슨 일이 당신이 실행하는 쉘인지 여부에서 따라 자신을 POSIX 모드. POSIX에서는 POSIX 호환 쉘이에 대한 응답으로 특정 방식으로 동작해야 ENOEXEC합니다. 그러나 "쉘을 호출하는 것과 동등한 명령"에는 약간의 차이가 있는데, 이는 다른 쉘이 다른 일을한다는 것을 의미합니다.

  • Bourne Again 쉘 은 스크립트 이름을 첫 번째 명령 행 인수와 동일한 모드다시 실행합니다 . POSIX 호환 모드에서는 물론 POSIX 호환 모드로 실행되므로 POSIX 호환 쉘을 호출하기위한 POSIX 요구 사항을 준수합니다.
  • Z 쉘, Almquist 쉘 및 Korn 쉘 /bin/sh은 첫 번째 명령 행 인수로 다른 인수 앞에 삽입 된 스크립트 이름으로 실행 됩니다. Z 쉘, Almquist 쉘 및 Korn 쉘은 /bin/sh프로그램이 하나 라고 가정하여 POSIX 호환 쉘을 호출하려고 시도 합니다.

이 C 프로그램의 소스 코드를 공유해 주
시겠습니까?

int main(int argc, char *argv[]){printf("I am %s\n",argv[0]);}
Stig Hemmer

거의 다됐다.
ilkkachu

4

실행 쉘은 중 하나를 명령 줄이나 오두막에서 하나 (명령 줄을 지정하지 않는 경우)에서 호출 한.

따라서 버전 1과 4는 sh, 2와 5는 bash로 실행되며 sh (및 다른 일부)를 대화식으로 사용하는 경우 6이 실행 되지 않을 수 있습니다 . Bash는 스크립트를 시작합니다. Ksh도. Zsh가 sh로 시작합니다.

shbash가에 연결된 경우 시작된 사용자 만 posix 옵션을 사용합니다 /bin/sh.

이 줄을 스크립트에 추가하여 bash ksh 또는 zsh 버전이 실행 중인지 감지하십시오.

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