bash 대체와 파이프의 차이점은 무엇입니까?

bash 대체와 파이프의 차이점은 무엇입니까?

저는 다음 두 명령을 실행하고 있습니다.

echo $(find ./ $OPT1 $OPT2 $OPT3)
echo find ./ $OPT1 $OPT2 $OPT3 | bash

이상하게도 top 명령은 결과가 나오지 않는 반면, lower 명령은 결과가 나옵니다. 왜 그런 겁니까?

답변1

첫 번째는 find ./ $OPT1 $OPT2 $OPT3토큰화를 실행하고 전역(따옴표 없이)을 출력 하고 이를 인쇄하는 $()에 전달합니다 . echo이는 기본적으로 명령을 실행하는 것과 동일 find하지만 개행 문자는 공백이 되며 파일 이름이 포함 find되거나 인쇄되면 확장됩니다. 그러나 콘텐츠에 특이한 내용이 포함되어 있으면 단어 분할도 마찬가지로 이상할 것입니다. (또한 다른 것들은 참조되지 않으므로 에 전달되기 전에 분할되고 와일드카드됩니다 .)*?IFS$OPT1find

두 번째는 를 인쇄하고 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

관련 정보