제 생각에는원천(즉.부르다) 모든 쉘의 스크립트(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_document
bash에서는 허용되지만 다른 쉘에서는 불법인 모든 조합의 모든 문자를 다른 쉘과 혼동하지 않고 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=:#
, 에서는 별도의 태그가 아니기 때문에 그렇지 않습니다 . 따라서 다음 내용은 주석 처리되었지만 주석 처리되지는 않았습니다 .#
csh
sh
csh
sh
- 변수 할당은
sh
성공적인 종료 상태(할당에 명령 대체가 포함되지 않는 한)이므로||
운영자의 명령 권한으로 실행되지 않습니다. - 명령 은
:<<"goto end="...goto end
실행되지 않지만 구문 분석되고 무시됩니다("goto end"
여기 문서 내에서 다양한 확장을 방지하는 사실이 인용됨). 하지만 참고하세요: Bourne 셸(Bourne 셸만 해당)에서는 임시 파일이 계속 생성됩니다. goto end=
따라서 Bourne과 같은 쉘에서는 전체 부분이 무시되고 및 사이의 부분은csh
. (Bourne과 같은 쉘에서 무해한 변수 할당)goto end=
로 인해 발생합니다 .csh
end=:
더 많은 쉘 지원을 추가할수록 더 까다로워집니다. fish
특히 전체 스크립트의 구문은 물론, 실행되지 않는 부분까지 검사하기 때문에 까다롭습니다.
또한보십시오:
- 런타임 시 스크립트에서 셸 결정다국어 코드의 예.
- 원격 사용자의 로그인 셸을 모르고 SSH를 통해 임의의 간단한 명령을 어떻게 실행할 수 있습니까?sh/csh/rc/fish 계열에 대한 코드(
parallel
쉘 호출에 대해 논의할 때 작성한 코드입니다)
답변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 사람들은 스크립트가 모든 환경에서 실행되도록 하기 위해 많은 영리한 작업을 수행합니다.