모든 쉘에서 실행되는 쉘 스크립트 작성(여러 개의 shebang 라인 사용?)

모든 쉘에서 실행되는 쉘 스크립트 작성(여러 개의 shebang 라인 사용?)

저는 이제 막 쉘 스크립팅에 대해 더 깊이 알아보기 시작했고 항상 스크립트를 파일에 넣고 표시한 chmod +x다음 완료 /path/to/script.sh하고 기본값인 인터프리터가 무엇이든 그대로 작동하도록 했습니다. 그게 zsh라고 가정했기 때문입니다. 나는 내 껍질에 사용했습니다. 분명히 zsh 프롬프트에서 스크립트를 실행하더라도 기본적으로 설정된 것 같습니다 /bin/sh. 왜냐하면 스크립트에 zsh 관련 내용을 넣기 시작했고 zsh /path/to/script.sh.

요점을 말하자면, 내 질문은 다음과 같습니다.

  1. #!/path/to/shell처음에 shebang 라인( )이 없을 때 스크립트를 실행하는 쉘은 무엇입니까 ? 추측하고 /bin/sh있지만 확인할 수는 없습니다.
  2. 모든 플랫폼에서 실행되는 셸 스크립트 작성과 관련하여 "모범 사례"로 간주되는 것은 무엇입니까? (좋아, 이건 일종의 개방형이야)
  3. zsh를 사용하려고 시도하고 zsh를 사용할 수 없는 경우 bash로 대체하는 스크립트를 작성할 수 있습니까? 아래와 같이 두 개의 shebang 라인을 넣으려고 시도했지만 bad interpreter: /bin/zsh: no such file or directoryzsh가 없는 시스템에서 시도하면 오류가 발생합니다.

    #!/bin/zsh

    #!/bin/bash

답변1

처음에 shebang 라인(#!/path/to/shell)이 없을 때 어떤 쉘이 스크립트를 실행합니까? /bin/sh라고 가정하지만 확인할 수 없습니다.

커널은 이러한 스크립트 실행을 거부하고 ENOEXEC를 반환하므로 정확한 동작은 해당 스크립트를 실행하는 프로그램에 따라 다릅니다.~에서.

  • bash 4.2.39 – 자체적으로 사용
  • busybox-ash 1.20.2 – 자체적으로 사용
  • 대시 0.5.7 – /bin/sh 실행
  • fish 1.23.1 – ENOEXEC에 대해 불평하고 잘못된 파일을 비난합니다.
  • AT&T ksh 93u+2012.08.01 – 자체 사용
  • mksh R40f – /bin/sh 실행
  • pdksh 5.2.14 – /bin/sh 실행
  • sh-heirloom 050706 – 자체적으로 사용
  • tcsh 6.18.01 – /bin/sh 실행
  • zsh 5.0.0 – /bin/sh 실행
  • cmd.exe 5.1.2600 – 당신을 재미있게 봅니다.

~ 안에glibc, 함수를 사용 execv()하거나 execve()ENOEXEC를 반환합니다. 하지만 execvp()이 오류 코드를 숨기고 자동으로 /bin/sh를 호출합니다. (이 내용은 다음 문서에 설명되어 있습니다.실행(3p).)

모든 플랫폼에서 실행되는 셸 스크립트 작성과 관련하여 "모범 사례"로 간주되는 것은 무엇입니까? (좋아, 이건 일종의 개방형이야)

POSIX에서 정의한 기능만 고수하거나 sh전체 기능을 사용하세요.세게 때리다(널리 사용 가능) 배포하는 경우 요구 사항에 언급하세요.

(지금 생각해보면 Perl 또는 아마도 Python은 더 나은 구문을 갖는 것은 말할 것도 없고 훨씬 더 이식성이 뛰어날 것입니다.)

언제나shebang 라인을 추가하십시오. bash 또는 zsh를 사용하는 경우 #!/usr/bin/env bash셸 경로를 하드코딩하는 대신 사용하세요. (단, POSIX 쉘은 에 있을 것을 보장하므로 그 경우에는 /bin/sh건너뛴다 .)env

(불행히도 even은 /bin/sh항상 같은 것은 아닙니다. GNU자동 구성프로그램이 처리해야 할여러 가지 특이한 점.)

zsh를 사용하려고 시도하고 zsh를 사용할 수 없는 경우 bash로 대체하는 스크립트를 작성할 수 있습니까? 아래와 같이 두 개의 shebang 줄을 넣으려고 시도했지만 오류가 발생했습니다.잘못된 해석기: /bin/zsh: 해당 파일이나 디렉터리가 없습니다.zsh가 없는 컴퓨터에서 시도해 보면 알 수 있습니다.

shebang 줄은 하나만 있을 수 있습니다. 개행 문자 이후의 모든 내용은 커널에서 읽혀지지 않으며 쉘에서 주석으로 처리됩니다.

그것은가능한로 실행되는 스크립트를 작성하고 #!/bin/sh, 사용 가능한 쉘을 확인하고, 결과에 따라 exec zsh "$0" "$@"실행 됩니다. exec bash "$0" "$@"그러나 bash와 zsh에서 사용하는 구문은 여러 위치에서 너무 다르기 때문에이 작업을 권장하지 않습니다당신 자신의 정신을 위해.

답변2

1) 현재 실행 중인 쉘. (어떤 쉘이든)

2) 동일한 쉘 유형(bash/dash/ash/csh/원하는 대로)을 고수하고 "지원되는 플랫폼"이 기본적으로 사용하려는 쉘을 설치하는지 확인하십시오. 또한 시스템에서 일반적으로 사용 가능한 명령을 사용해 보십시오. 기계별 옵션은 피하세요.

3) 실제로 "if-then-else" 논리가 없습니다 interpreter directive. 지원하려는 모든 시스템에 존재해야 하는 쉘을 지정해야 합니다. 즉, 스크립트가 모든 쉘에서 상당히 일반적인 경우 #!/bin/bash일반을 지정해야 합니다 .#!/bin/sh

관련 정보