쉘 기반 "스위치"

쉘 기반 "스위치"

제 생각에는원천(즉.부르다) 모든 쉘의 스크립트(bash/csh가 주요 대상이지만 Fish, zsh, ksh 및 rc도 흥미롭습니다).

나는 스크립트가 단일 파일이기를 바랐습니다. 즉, 각 쉘 방언에 대한 파일이 아닙니다.

내가 이걸 할 수 있을까?

나는 다음과 같은 것을 생각하고 있습니다 :

  if shell is bash then
    # bash code here
  else
    if shell is csh then
      # csh code here
    else
      if shell is xxxsh then
        # xxxsh code here
      fi
    endif
  fi

그래서 나는 이것을 할 수 있습니다 :

csh% source my_script
bash$ . my_script

문제는 - 물론 if모든 방언이 다르기 때문에 모든 쉘에 작동하는 구문을 사용해야 한다는 것입니다.

편집하다

쉘을 감지하는 것이 첫 번째 단계입니다.런타임 시 스크립트에서 셸 결정잘하셨어요.

마찬가지로 중요한 단계는 다른 쉘을 혼동하지 않도록 쉘의 다른 부분에서 코드를 참조하는 방법입니다. 생각해 보세요: <<here_documentbash에서는 허용되지만 다른 쉘에서는 불법인 모든 조합의 모든 문자를 다른 쉘과 혼동하지 않고 bash 섹션에 어떻게 포함시킬 수 있습니까? 답변/링크된 답변 중 어느 것도 이를 다루지 않습니다.

답변1

모든 셸에 대해 코드 조각을 작성해서는 안 되며 대부분의 셸에서 해석할 수 있는 이식 가능한 코드만 작성해야 합니다. 너는 좀 봐야 해POSIX 쉘 명령 언어. 이는 쉘(POSIX 이후)이 코드를 해석하는 방법에 대한 표준입니다.

많은 셸(예 bash: )이 POSIX 셸처럼 실행되도록 구성할 수 있습니다. 각 셸에는 고유한 기능과 특정 기호가 있습니다. 이식 가능한 스크립트에서는 완전히 사용하지 마십시오.

답변2

csh와 유사한 상황 및 Bourne과 유사한 상황에서는 다음을 수행할 수 있습니다.

start=:#||:<<"goto end="

echo "(t)csh code here"
if { bindkey >& /dev/null } then
  echo tcsh
endif

goto end=

echo Bourne-like code here
if [ -n "$BASH_VERSION" ]; then
  echo bash
fi

end=:

설명하다:

  • start=:에서는 레이블 선언 csh과 ​​에서는 변수 할당 으로 처리되므로 sh두 가지 무해한 작업입니다.
  • 에서는 주석 리더로 간주되지만 start=:#, 에서는 별도의 태그가 아니기 때문에 그렇지 않습니다 . 따라서 다음 내용은 주석 처리되었지만 주석 처리되지는 않았습니다 .#cshshcshsh
  • 변수 할당은 sh성공적인 종료 상태(할당에 명령 대체가 포함되지 않는 한)이므로 ||운영자의 명령 권한으로 실행되지 않습니다.
  • 명령 은 :<<"goto end="...goto end실행되지 않지만 구문 분석되고 무시됩니다( "goto end"여기 문서 내에서 다양한 확장을 방지하는 사실이 인용됨). 하지만 참고하세요: Bourne 셸(Bourne 셸만 해당)에서는 임시 파일이 계속 생성됩니다.
  • goto end=따라서 Bourne과 같은 쉘에서는 전체 부분이 무시되고 및 사이의 부분은 csh. (Bourne과 같은 쉘에서 무해한 변수 할당) goto end=로 인해 발생합니다 .cshend=:

더 많은 쉘 지원을 추가할수록 더 까다로워집니다. fish특히 전체 스크립트의 구문은 물론, 실행되지 않는 부분까지 검사하기 때문에 까다롭습니다.

또한보십시오:

답변3

이 작업을 수행하려는 이유는 이식성 때문이라고 생각합니다. 위의 답변은 단서를 제공합니다. Bourne 쉘(sh)이 최소 공통 분모이고 "모든 곳"(Linux, Solaris, Unix, AIX 등)에서 사용할 수 있다고 가정하면 #!/bin/sh이를 스크립트 시작 부분에 추가하고 모든 스크립트를 작성할 수 있습니다. sh의 기능만 사용합니다. (내 생각에 Linux에서는 bash가 Bourne 쉘의 상위 집합이기 때문에 sh는 bash의 별칭일 뿐이지만 관계없이 계속 작동해야 합니다.)

항상 존재 한다고 가정하여 조금 개선하십시오 sh. 하지만 고급 쉘의 추가 성능과 편리함을 원할 수도 있습니다. 따라서 script.bash, script.zsh, script.ksh, script.csh 등과 같이 지원하는 각 셸에 대한 스크립트 버전을 작성할 수 있습니다. 각 스크립트는 자체 shebang 줄로 시작한 다음 스크립트 내에서 시작됩니다. sh 파일을 사용하면 다음과 같이 말할 수 있습니다.

#!/bin/sh
if [[ -e /bin/ksh ]] ; then 
 ./script.ksh
 exit
elif [[ -e /bin/csh ]] ; then
 ./script.csh
 exit
fi

등.

추가 제안은 자동 도구 도구 모음의 소스 코드를 연구하는 것입니다. ./configure를 수행할 때 실행되는 것입니다. GNU 사람들은 스크립트가 모든 환경에서 실행되도록 하기 위해 많은 영리한 작업을 수행합니다.

관련 정보