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

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

나는 이 콘텐츠에서 다음 내용을 읽었습니다.질문:

bash는 --posix 스위치를 지원하므로 POSIX와 더욱 호환됩니다. 또한 다음과 같은 경우 POSIX를 모방하려고 시도합니다.sh라고 불림.

위의 인용문은 /bin/sh에 대한 링크로 간주됩니다 /bin/bash.

하지만 그게 무슨 뜻인지 잘 이해가 안 돼요."sh로 전화해".


"script.sh"라는 다음 스크립트가 있다고 가정해 보겠습니다.

#!/bin/bash
echo "Hello World"

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

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

이제 "script.sh"라는 다음 스크립트가 있다고 가정해 보겠습니다(위의 스크립트와 유사하지만 shebang이 없음).

echo "Hello World"

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

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

답변1

사례 1과 4만 POSIX 모드에서 실행됩니다( shbash를 가정하고 sh의 다른 구현은 가정하지 않음). shebang에서든 아니든 상관 없이 bashWithout 에 대한 명시적인 호출입니다 . --posixwill이 명시적으로 호출되는 모든 상황 sh. shebang은 스크립트에 대해 쉘이 명시적으로 시작되지 않은 경우에만 사용됩니다.

사례 6, 터미널이 실행 중인 경우 bashPOSIX 모드에서 실행되고 있지 않으며Bash는 자신을 사용하여 이를 호출합니다. 터미널이 zsh를 실행 중인 경우 사례 6회의POSIX 모드에서도 실행됩니다. POSIX는 이 경우 정확히 무슨 일이 일어나야 하는지 불분명합니다., Bash와 zsh는 거기서 다른 선택을 합니다. Bash는 자체적으로 스크립트를 호출하는 반면 zsh는 sh(어떤 일이 일어나든) 사용합니다. 다른 쉘도 이 점에서 다릅니다.


현재 어떤 모드에 있는지 확인하는 쉬운 방법은 스크립트 본문을 만드는 것입니다.

kill -SIGHUP

이것은 것이다POSIX 모드에서 오류로 인해 실패함kill, 그러나 사용에 대한 외부 지침을 제공합니다. 이는 광범위한 Bash 버전에 적용되는 간단한 구별이며, 발생할 수 있는 버전으로 돌아갑니다.

답변2

"호출자"는 Bash를 시작하는 프로세스가 "0번째" 명령줄 인수에 입력하는 모든 것을 나타냅니다 argv[0].

프로그램이 시작되면exec*()시스템 호출, 그들은 프로그램이 포함된 바이너리의 이름을 실제로 알지 못하지만 호출 프로세스는 원하는 것을 자유롭게 넣을 수 있습니다. 물론 일반적으로 이름은 파일 시스템에서 가져오므로 를 실행하면 /bin/sh해당 이름이 해당 파일 시스템에 입력됩니다. Bash 라면 /bin/sh심볼릭 링크일 필요는 없습니다. 하드 링크일 수도 있고 쉘 프로그램의 또 다른 복사본일 수도 있습니다.

"프로그램 이름" 설정의 예로 Bash의 exec명령은 옵션을 사용하여 0번째 인수를 설정할 수 있습니다 -a. (Perl을 사용하거나 C 등을 사용하여 동일한 작업을 수행할 수 있습니다.)

다음은 myname0번째 인수, 즉 표시되는 이름을 인쇄하는 간단한 C 프로그램입니다.

$ ./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) run은 가지고 있는 모든 것을 sh somescript실행합니다 . 그러나 아마도shPATH/bin/sh이럴 수도 있지/usr/xpg4/bin/sh.

  • Bash인 경우 이름이 표시되므로 POSIX 모드에서 실행됩니다 sh.
  • Z 쉘 또는 Korn 쉘인 경우 이름도 표시되지만 shBourne 쉘과 호환되도록 고안된 "SH 호환성" 모드에서 실행되며 전체 POSIX 적합성 모드와는 약간 다릅니다. 그 두 껍질은 다릅니다.
  • 물론 Almquist 쉘, 실제 Bourne 쉘 또는 다른 것일 수도 있습니다.

(2 & 5)는 bash somescript일반 Bash 모드에서 실행됩니다. (물론 콘텐츠에 따라 다릅니다 bash. PATH)

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

(6) 이것은 복잡한 문제이다. (3)과 유사하지만, ENOEXEC (Exec format error)해시뱅 라인이 없기 때문에 프로그램을 시작하는 시스템 호출이 실패합니다( ). 다음에 일어날 일은 실행 중인 쉘이 다음인지 여부에 따라 다릅니다.그 자체POSIX 모드에서.POSIX에서는 특정 방식으로 응답하기 위해 POSIX 호환 쉘이 필요합니다 ENOEXEC. 그러나 "쉘을 호출하는 것과 동일한 명령"에는 약간의 여유가 있습니다. 이는 다른 쉘이 다른 작업을 수행한다는 것을 의미합니다.

  • 본 아이덴티티 쉘같은 모드로 다시 실행첫 번째 명령줄 인수로 스크립트 이름을 지정합니다. POSIX 호환 모드에서는 물론 POSIX 호환 모드에서 자체적으로 실행되므로 POSIX 호환 셸 호출을 위한 POSIX 요구 사항을 준수합니다.
  • Z 쉘, Almquist 쉘 및 Korn 쉘은 /bin/sh다른 매개변수 앞에 첫 번째 명령줄 인수로 삽입된 스크립트 이름을 사용하여 실행됩니다. Z 쉘, Almquist 쉘 및 Korn 쉘(시도)은 /bin/sh프로그램이 POSIX 호환 쉘이라고 가정하여 POSIX 호환 쉘을 호출합니다.

답변3

실행 쉘은누구나명령줄에서 호출된 것 또는 명령줄에서 지정하지 않은 경우 shebang에서 호출된 것입니다.

따라서 버전 1과 4는 실행되고 sh, 버전 2와 5는 bash를 사용하여 실행될 수 있으며, 버전 6은 다음을 사용하여 실행될 수 있습니다.아니요sh(및 기타 일부)를 대화식으로 사용하는 경우 를 실행하십시오. Bash는 스크립트를 시작합니다. 케시도요. Zsh는 sh로 시작합니다.

shbash가 연결되어 있으면 as로 시작한 것만 posix 옵션을 사용합니다 /bin/sh.

bash ksh 또는 zsh 버전이 실행 중인지 확인하려면 스크립트에 다음 줄을 추가하세요.

echo "Hello World $BASH_VERSION $KSH_VERSION $ZSH_VERSION"

관련 정보