저는 다음 두 명령을 실행하고 있습니다.
echo $(find ./ $OPT1 $OPT2 $OPT3)
echo find ./ $OPT1 $OPT2 $OPT3 | bash
이상하게도 top 명령은 결과가 나오지 않는 반면, lower 명령은 결과가 나옵니다. 왜 그런 겁니까?
답변1
첫 번째는 find ./ $OPT1 $OPT2 $OPT3
토큰화를 실행하고 전역(따옴표 없이)을 출력 하고 이를 인쇄하는 $()
에 전달합니다 . echo
이는 기본적으로 명령을 실행하는 것과 동일 find
하지만 개행 문자는 공백이 되며 파일 이름이 포함 find
되거나 인쇄되면 확장됩니다. 그러나 콘텐츠에 특이한 내용이 포함되어 있으면 단어 분할도 마찬가지로 이상할 것입니다. (또한 다른 것들은 참조되지 않으므로 에 전달되기 전에 분할되고 와일드카드됩니다 .)*
?
IFS
$OPT1
find
두 번째는 를 인쇄하고 find ./ $OPT1 $OPT2 $OPT3
변수를 확장한 다음(따옴표가 없으므로 다시 분할하고 와일드카드 사용) 결과를 bash
명령으로 실행하는 에 전달합니다. running 과 거의 동일 find
하지만 변수에 셸 메타 문자가 포함되어 있으면 두 번째 셸에 의해 (다시) 확장됩니다.
먼저 파일 이름이 foo*
확장되어 세 가지 모두 와일드카드로 표시됩니다.
$ touch foo1 foo2 foo\*
$ echo $(find .)
. ./foo2 ./foo* ./foo1 ./foo2 ./foo1
둘째, bash의 파이핑으로 인해 사용한 것과 같은 내부 변수가 확장된다는 점에 유의하세요 eval
.
$ OPT='echo $BASH_VERSION'
$ echo $OPT
echo $BASH_VERSION
$ echo $OPT | bash
4.3.30(1)-release
$ eval $OPT # about the same
4.3.30(1)-release
BASH_VERSION
변수 확장은 아마도 가장 간단한 예일 것입니다. 그러나 아래 표시된 것처럼 어떤 경우든 내보낸 변수나 쉘에 있는 다른 변수가 필요합니다 . ( find
지금으로서는 합리적인 예가 생각나지 않습니다.)
변수에 포함된 내용에 따라 추가 평가 라운드를 통해 OPT
일치 여부가 달라질 수 있습니다.find