깨끗한 환경에서 스크립트를 시작하는 방법은 무엇입니까?


15

다음을 시도했지만 작동하지 않는 것 같습니다.

$ cat script.sh
#!/bin/env -i /bin/sh

/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.

비슷한 질문을 찾았지만 오두막에서 수행하는 방법을 보여주지 않습니다 unix.stackexchange.com/questions/48994/...
balki

5
당신은 shebang에서 그것을 할 수 없습니다. shebang은 하나의 인수 만 허용합니다.
jordanm

답변:


7

이것이 작동하지 않는 이유는 -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환경 변수를 설정하지 않으면 스크립트가 다시 실행됩니다 . 그런 다음 다시 실행하면 변수가 루프에 들어 가지 않도록 변수를 설정합니다.


envGNU coreutils -S에서이 문제와 비슷한 문제를 해결할 수있는 옵션 이 있지만 정확히 같은 것은 아닙니다. 예를 들어 #!/usr/bin/env -S perl -T.
Weijun Zhou

방금 시도했습니다. 원래 질문에도 적용됩니다. 그냥 사용하십시오 #!/usr/bin/env -S -i /bin/sh. 이식성 문제에 유의하십시오.
Weijun Zhou

3

다음을 사용하여 스크립트를 실행하십시오 env -i.

env -i script.sh

그리고 평소와 같이 스크립트 :

#!/bin/sh
# ... your code here

당신이 달리 말할 때 명시 적으로 말하지 않고 깨끗한 환경에서 실행하려는 경우. Eduardo Ivanec 은이 답변에 몇 가지 아이디어를 제공 exec합니다. 환경이 깨끗하지 않을 때 스크립트를 재귀 적으로 호출 할 수 있습니다 (예 : $ HOME이 정의 됨).

[ "$HOME" != "" ] && exec -c $0

좋은. 그냥 내가했던 것처럼 env -i bash를하지 말고 왜 env 변수가 여전히 설정되어 있는지 궁금해하십시오 (물론 bash 리소스 .bashrc 및 친구 8)
Neil McGill

2

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 -eset -u 명령은 반드시 필요한 것은 아니지만, 나는 그들이이 방법은 (예로 설정되지 않은 변수를 액세스에 의존하지 않는다는 것을 보여주기 위해 포함 [ "$HOME" != "" ]것)과와 호환되는 set -e설정.

HOMEbash는 비 대화식 모드에서 스크립트를 실행하기 때문에 변수를 테스트하는 것이 안전해야합니다. 즉 ~/.bashrc(환경 변수가 설정 될 수있는) 와 같은 구성 파일 은 시작 중에 소스되지 않습니다.

출력 예 :

declare -x OLDPWD
declare -x PWD="/home/juser"
declare -x SHLVL="1"

0

$ cat script.sh

#!/bin/env -i /bin/sh

슬프게도 그렇게 작동하지 않습니다. Linux는 -i /bin/sh전달할 하나의 주장으로 간주 합니다 env( Shebang 참조 ).


0

리눅스 2- 인수 shebang 제한 (interpeter + single argument)은 대부분의 답변에 언급되어 있지만 이것이 불가능하다는 것은 잘못된 것입니다. 단일 인수로 유용한 것을 수행 할 수있는 인터프리터로 변경하면됩니다.

#!/usr/bin/perl -we%ENV=();exec "/bin/sh " . join " ", map "'$_'", @ARGV;
# your sh script here

이 작업은 인수를 올바르게 인용하여을 지우고 (보다 저렴 ) 호출 perl하는 단일 라이너 스크립트 ( -e)로 호출합니다 . 또한 필요한 경우 (당신이로 제한하고 있기 때문에별로 리눅스하지만 논리는, 추가 할 수있는 문자 가능성이 128 인)%ENVenv -iexec /bin/shperlBINPRM_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의 다중 인수를 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.