다음을 시도했지만 작동하지 않는 것 같습니다.
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
다음을 시도했지만 작동하지 않는 것 같습니다.
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
답변:
이것이 작동하지 않는 이유는 -i /bin/sh
에 대한 단일 인수로 간주되기 때문 env
입니다. 보통이 2 인자 될 것입니다 -i
및 /bin/sh
. 이것은 단지 세방의 한계입니다. 주위에 방법이 없습니다.
그러나 여전히 다른 방법으로이 작업을 수행 할 수 있습니다.
이 작업을 스크립트 자체에서 수행하고, 같은 작업을 수행하지 않으려면 스크립트 자체를 env -i script.sh
다시 실행할 수 있습니다.
#!/bin/sh
[ -z "$CLEANED" ] && exec /bin/env -i CLEANED=1 /bin/sh "$0" "$@"
CLEANED
환경 변수를 설정하지 않으면 스크립트가 다시 실행됩니다 . 그런 다음 다시 실행하면 변수가 루프에 들어 가지 않도록 변수를 설정합니다.
env
GNU coreutils -S
에서이 문제와 비슷한 문제를 해결할 수있는 옵션 이 있지만 정확히 같은 것은 아닙니다. 예를 들어 #!/usr/bin/env -S perl -T
.
#!/usr/bin/env -S -i /bin/sh
. 이식성 문제에 유의하십시오.
다음을 사용하여 스크립트를 실행하십시오 env -i
.
env -i script.sh
그리고 평소와 같이 스크립트 :
#!/bin/sh
# ... your code here
당신이 달리 말할 때 명시 적으로 말하지 않고 깨끗한 환경에서 실행하려는 경우. Eduardo Ivanec 은이 답변에 몇 가지 아이디어를 제공 exec
합니다. 환경이 깨끗하지 않을 때 스크립트를 재귀 적으로 호출 할 수 있습니다 (예 : $ HOME이 정의 됨).
[ "$HOME" != "" ] && exec -c $0
bash를 사용하면 다음과 같이 할 수 있습니다.
#!/usr/bin/bash
set -e
set -u
[ -v HOME ] && exec -c "$0" "$@"
# continue with the rest of the script
# e.g. print the cleaned environment:
export
set -e
및 set -u
명령은 반드시 필요한 것은 아니지만, 나는 그들이이 방법은 (예로 설정되지 않은 변수를 액세스에 의존하지 않는다는 것을 보여주기 위해 포함 [ "$HOME" != "" ]
것)과와 호환되는 set -e
설정.
HOME
bash는 비 대화식 모드에서 스크립트를 실행하기 때문에 변수를 테스트하는 것이 안전해야합니다. 즉 ~/.bashrc
(환경 변수가 설정 될 수있는) 와 같은 구성 파일 은 시작 중에 소스되지 않습니다.
출력 예 :
declare -x OLDPWD
declare -x PWD="/home/juser"
declare -x SHLVL="1"
리눅스 2- 인수 shebang 제한 (interpeter + single argument)은 대부분의 답변에 언급되어 있지만 이것이 불가능하다는 것은 잘못된 것입니다. 단일 인수로 유용한 것을 수행 할 수있는 인터프리터로 변경하면됩니다.
#!/usr/bin/perl -we%ENV=();exec "/bin/sh " . join " ", map "'$_'", @ARGV;
# your sh script here
이 작업은 인수를 올바르게 인용하여을 지우고 (보다 저렴 ) 호출 perl
하는 단일 라이너 스크립트 ( -e
)로 호출합니다 . 또한 필요한 경우 (당신이로 제한하고 있기 때문에별로 리눅스하지만 논리는, 추가 할 수있는 문자 가능성이 128 인)%ENV
env -i
exec /bin/sh
perl
BINPRM_BUF_SIZE
슬프게도, 이것은 Linux에만 해당되며 여러 shebang 인수를 허용하는 시스템에서는 작동하지 않습니다 :-/
perl
이 문자열을 단일 인수로 처리하므로 일반적으로 명령 줄에서 와 같이 위에서 인용되지 않습니다perl -e ...
(따옴표를 추가하는 경우 유지됩니다. 일정한).
또한이 방법을 사용할 때의 행동에 약간의 변화가있어주의 @ARGV
일반적으로 인수 만 포함하고, $0
스크립트를 포함하고 있지만이 오두막으로 $ARGV[0]
스크립트의 이름입니다 (그리고 $0
것입니다 -e
좀 더 쉽게 그것을 만드는).
또한 -c
고대 AT & T ksh93
가 수행 하는 명령 줄을 (추가 인수 없이) "재 처리"하는 해석기로이 문제를 해결할 수 있습니다 .
#!/bin/ksh /usr/bin/env -i /bin/sh
ksh
요즘 아마 평범 하지는 않지만 ;-)
( bash
와 비슷한 기능이 있습니다 --wordexp
, 하지만 그것은 작동하고,이 설명되어있는 버전에서 컴파일시에 사용할 수 없습니다 버전의 "불법"입니다 : - 그것은 두 개의 인수를 필요로하기 때문에 / 그것은이 사용할 수 없습니다. ..)
또한 @Patrick 및 @maxschlepzig의 답변에 대한 변형을 효과적으로 나타냅니다.
#!/bin/bash
[ "$_" != bash ] && exec -c -a "bash" /bin/bash "$0" "$@"
# your script here
오히려 새로운 변수를 사용하는 것보다이 사용하는 특별한 " _
bash는"이 정확히 설정되어 있지 않은 경우 변수 ","다음에 스크립트를 대체 exec
사용 -a
하기 위해 ARGV[0]
(따라서 $_
"bash는, 및 사용) 단지를" -c
환경을 취소 할 수 있습니다.
또는 스크립트 시작시 환경을 정리할 수있는 경우 (bash 만) :
#!/bin/sh
unset $(compgen -e)
# your script here
compgen
(완료 도우미)를 사용 하여 내 보낸 모든 환경 변수의 이름을 나열하고 unset
한 번에 s를 지정합니다.
shebang 동작의 일반적인 문제에 대한 자세한 내용 은 shebang의 다중 인수를 참조하십시오 .