답변:
eval "$1"
현재 스크립트에서 명령을 실행합니다. 현재 스크립트에서 쉘 변수를 설정 및 사용하고, 현재 스크립트에 대한 환경 변수를 설정하고, 현재 스크립트에서 기능을 설정 및 사용하고, 현재 디렉토리에 대한 현재 디렉토리, umask, limit 및 기타 속성을 설정하는 등의 작업을 수행 할 수 있습니다. bash -c "$1"
환경 변수, 파일 디스크립터 및 기타 프로세스 환경을 상속하지만 변경 사항을 다시 전송하지는 않지만 내부 쉘 설정 (쉘 변수, 함수, 옵션, 트랩 등)은 상속하지 않는 완전히 별도의 스크립트로 명령을 실행합니다.
(eval "$1")
서브 쉘에서 명령을 실행하는 또 다른 방법이 있습니다 . 호출하는 스크립트에서 모든 것을 상속하지만 변경 사항을 다시 전송하지는 않습니다.
예를 들어, 변수가 가정 dir
수출되지 않고 $1
있다 cd "$foo"; ls
다음 :
cd /starting/directory; foo=/somewhere/else; eval "$1"; pwd
내용 /somewhere/else
및 인쇄 내용을 나열 합니다 /somewhere/else
.cd /starting/directory; foo=/somewhere/else; (eval "$1"); pwd
내용 /somewhere/else
및 인쇄 내용을 나열 합니다 /starting/directory
.cd /starting/directory; foo=/somewhere/else; bash -c "$1"; pwd
/starting/directory
( cd ""
현재 디렉토리를 변경하지 않기 때문에) 의 내용을 나열 하고 인쇄합니다 /starting/directory
.(eval "$1")
는 아무 관련 이 없습니다 source
. 그것은 단지의 조합이다 (…)
와 eval
. source foo
대략과 같습니다 eval "$(cat foo)"
.
eval
과는 .dot
즉 eval
와 작품 의 인수 와 .dot
함께 작동 파일입니다.
가장 중요한 차이점
bash -c "$1"
과
eval "$1"
전자는 서브 쉘에서 실행되고 후자는 그렇지 않습니다. 그래서:
set -- 'var=something'
bash -c "$1"
echo "$var"
#there doesn't seem to be anything here
set -- 'var=something'
eval "$1"
echo "$var"
something
그래도 왜 누군가가 bash
그런 식으로 실행 파일 을 사용하는지 모르겠습니다 . 호출해야하는 경우 POSIX 보장 내장 기능을 사용하십시오 sh
. 또는 (subshell eval)
환경을 보호하려는 경우.
개인적으로, 나는 .dot
무엇보다 껍질을 선호합니다 .
printf 'var=something%d ; echo "$var"\n' `seq 1 5` | . /dev/fd/0
something1
something2
something3
something4
something5
실제로 변수를 사용하는 유일한 원인은 변수가 실제로 다른 변수를 할당하거나 평가하거나 단어 분할이 출력에 중요 할 때입니다.
예를 들어 :
var='echo this is var' ; $var
this is var
그것은 효과가 있지만 echo
인수 수에 신경 쓰지 않기 때문에 가능 합니다.
var='echo "this is var"' ; $var
"this is var"
보다? 쉘 확장 결과가에 대해 $var
평가되지 않기 때문에 큰 따옴표가 함께 표시 됩니다 quote-removal
.
var='printf %s\\n "this is var"' ; $var
"this
is
var"
그러나 eval
또는 sh
:
var='echo "this is var"' ; eval "$var" ; sh -c "$var"
this is var
this is var
우리가 사용할 때 eval
또는 sh
쉘은 확장 결과에서 두 번째 단계를 거쳐 잠재적 인 명령으로 평가하므로 따옴표는 차이를 만듭니다. 당신은 또한 할 수 있습니다 :
. <<VAR /dev/fd/0
${var:=echo "this is var"}
#END
VAR
this is var
나는 빠른 테스트를했다 :
time bash -c 'for i in {1..10000}; do bash -c "/bin/echo hi"; done'
time bash -c 'for i in {1..10000}; eval "/bin/echo hi"; done'
(예, bash -c를 사용하여 루프를 실행했지만 차이가 없어야합니다.)
결과 :
eval : 1.17s
bash -c : 7.15s
그래서 eval
빠릅니다. 의 맨 페이지에서 eval
:
평가 유틸리티는 인수를 서로 연결하여 각 문자를 분리하여 명령을 구성해야합니다. 작성된 명령은 쉘에 의해 읽고 실행되어야합니다.
bash -c
물론, bash 쉘에서 명령을 실행합니다. 참고 사항 :에 내장 된 쉘 /bin/echo
이므로 새 프로세스를 시작할 필요가 없으므로 사용했습니다. 교체 로 에 대한 테스트, 그것은했다 . 그것은 거의 같습니다. Hovever 는 실행 파일 실행 속도가 빠릅니다. 여기서 중요한 차이점은 새 쉘을 시작하지 않고 (현재 쉘에서 명령을 실행) 새 쉘을 시작한 다음 새 쉘에서 명령을 실행한다는 것입니다. 새 셸을 시작하는 데 시간이 걸리므로 . 보다 느립니다 .echo
bash
/bin/echo
echo
bash -c
1.28s
eval
eval
bash -c
bash -c
eval
bash -c
과 함께 eval
하지 exec
.
bash -c
아닌 그 ... 나쁜
e='echo foo'; $e
잘 작동합니다.