tl; dr
발바닥 stuff
이 가장 효과적 일 것입니다.
전체 답변
무슨 일이야
를 실행하면 다음 foo $(stuff)
과 같은 일이 발생합니다.
stuff
달리기;
- 출력 (stdout)은 인쇄되는 대신
$(stuff)
다음을 호출하여 대체합니다 foo
.
- 그런 다음
foo
명령 줄 인수는 분명히 stuff
반환 된 내용에 달려 있습니다 .
이 $(…)
메커니즘을 "명령 대체"라고합니다. 귀하의 경우 기본 명령은 echo
기본적으로 명령 줄 인수를 stdout에 인쇄하는 것입니다. 따라서 stuff
stdout으로 인쇄하려고 시도하는 모든 것이 캡처 echo
되어 stdout에 의해 인쇄됩니다 echo
.
출력 stuff
을 stdout으로 인쇄하려면 sole을 실행하십시오 stuff
.
이 `…`
구문은 $(…)
같은 이름 으로 (동일한 이름 : "명령 대체") 동일한 기능을 수행하지만 차이점은 거의 없으므로 맹목적으로 교환 할 수 없습니다. 참조 이 자주 묻는 질문 과 이 질문을 .
echo $(stuff)
무엇을 피해야 합니까?
echo $(stuff)
하고있는 일을 알고 있다면 사용하고 싶은 이유가 있습니다 . 같은 이유로 echo $(stuff)
당신이하고있는 일을 정말로 모른다면 피해야 합니다.
요점은 stuff
하고 echo $(stuff)
정확하게 해당되지 않습니다. 후자 stuff
는 기본값 인의 출력에서 split + glob 연산자를 호출하는 것을 의미 $IFS
합니다. 명령 대체를 큰 따옴표로 묶으면이를 방지 할 수 있습니다. 명령 인용을 작은 따옴표로 묶으면 더 이상 명령을 대체하지 않습니다.
분할 할 때이를 관찰하려면 다음 명령을 실행하십시오.
echo "a b"
echo $(echo "a b")
echo "$(echo "a b")" # the shell is smart enough to identify the inner and outer quotes
echo '$(echo "a b")'
그리고 globbing를 위해 :
echo "/*"
echo $(echo "/*")
echo "$(echo "/*")" # the shell is smart enough to identify the inner and outer quotes
echo '$(echo "/*")'
보시다시피 echo "$(stuff)"
(-ish *)와 같습니다 stuff
. 당신은 그것을 사용할 수 있지만 이런 식으로 문제를 복잡하게 만드는 요점은 무엇입니까?
반면에 당신이 경우 원하는 의 출력은 stuff
다음 글 로빙 분할 + 받아야 할 수 있습니다 찾을 수 echo $(stuff)
유용합니다. 그래도 의식적인 결정이되어야합니다.
셸에서 평가하고 (분할, globbing 등을 포함하여) 출력을 생성하는 명령 eval "$(stuff)"
이 있으므로 가능성이 있습니다 ( 이 답변 참조 ). 인쇄 하기 전에 추가 분할 + globbing을 수행하기 위해 출력이 필요한 명령을 본 적이 없습니다 . 의도적으로 사용하는 echo $(stuff)
것은 매우 드문 것 같습니다.
무엇에 대해 var=$(stuff); echo "$var"
?
좋은 지적. 이 스 니펫 :
var=$(stuff)
echo "$var"
echo "$(stuff)"
equal (-ish *)와 동일 해야합니다 stuff
. 전체 코드라면 stuff
대신 실행하십시오 .
그러나 출력을 stuff
두 번 이상 사용해야하는 경우이 접근법
var=$(stuff)
foo "$var"
bar "$var"
보통보다 낫다
foo "$(stuff)"
bar "$(stuff)"
하더라도 foo
이다 echo
당신이 얻을 echo "$var"
코드에서,이 방법을 유지하는 것이 더있을 수 있습니다. 고려해야 할 사항 :
- 으로
var=$(stuff)
stuff
실행 번; 명령이 빠르더라도 동일한 출력을 두 번 계산하지 않는 것이 옳습니다. 또는 stuff
stdout에 쓰는 것 (예 : 임시 파일 작성, 서비스 시작, 가상 머신 시작, 원격 서버에 알리기) 이외의 영향을 미치므로 여러 번 실행하고 싶지 않습니다.
stuff
시간 의존적이거나 다소 임의의 출력을 생성하는 경우 foo "$(stuff)"
및 에서 일관되지 않은 결과를 얻을 수 있습니다 bar "$(stuff)"
. 이후 var=$(stuff)
의 값 $var
과 고정 당신은 확신 할 수 foo "$var"
와 bar "$var"
동일한 명령 행 인수를 얻을.
경우에 따라, 대신 여러 인수를 생성 하는 경우 (쉘이 지원하는 경우 배열 변수가 더 나을 수 있음 foo "$var"
) 대신 (필요한)을 사용할 수도 있습니다. 다시, 당신이하고있는 일을 알고 있습니다. 그것은 올 때 의 차이 와 사이과 동일 하고 .foo $var
stuff
foo
echo
echo $var
echo "$var"
echo $(stuff)
echo "$(stuff)"
* 동등한 ( -ish )?
나는 echo "$(stuff)"
(-ish)와 동일 하다고 말했다 stuff
. 정확히 동일하지 않은 두 가지 문제가 있습니다.
$(stuff)
하위 셸 stuff
에서 실행 되므로 echo "$(stuff)"
에 해당하는 (-ish)와 같습니다 (stuff)
. 서브 쉘 인 경우 실행되는 쉘에 영향을주는 명령은 기본 쉘에 영향을 미치지 않습니다.
이 예 stuff
에서 a=1; echo "$a"
:
a=0
echo "$(a=1; echo "$a")" # echo "$(stuff)"
echo "$a"
그것을 비교
a=0
a=1; echo "$a" # stuff
echo "$a"
와
a=0
(a=1; echo "$a") # (stuff)
echo "$a"
또 다른 예는,로 시작 stuff
되는 cd /; pwd
:
cd /bin
echo "$(cd /; pwd)" # echo "$(stuff)"
pwd
테스트 stuff
및 (stuff)
버전.
echo
제어되지 않은 데이터를 표시하는 좋은 도구가 아닙니다 . 이것은 echo "$var"
우리에 대해 얘기했다가되어 있어야합니다 printf '%s\n' "$var"
. 그러나 질문에 언급 echo
되어 있고 가장 가능한 해결책은 echo
처음에는 사용 하지 않기 때문에 printf
지금까지 소개하지 않기로 결정했습니다 .
stuff
또는 (stuff)
stdout 및 stderr 출력을 인터리브하는 동시에 echo $(stuff)
모든 stderr 출력을 stuff
(먼저 실행) 에서 인쇄 한 다음 stdout 출력을 echo
(최종 실행)으로 인쇄합니다.
$(…)
후행 줄 바꿈을 제거한 다음 echo
다시 추가합니다. 따라서 echo "$(printf %s 'a')" | xxd
와 다른 출력을 제공합니다 printf %s 'a' | xxd
.
ls
예를 들어 일부 명령 은 표준 출력이 콘솔인지 아닌지에 따라 다르게 작동합니다. 그래서 ls | cat
동일하지 ls
않습니다. 마찬가지로 echo $(ls)
와 다르게 작동 ls
합니다.
퍼팅 ls
일반적인 경우에, 옆 경우 이 다른 행동을 한 후 강제로 stuff | cat
보다 더 나은 echo $(ls)
또는 echo "$(ls)"
이 다른 모든 문제는 여기에 언급 트리거하지 않기 때문에.
아마도 다른 종료 상태 (이 위키 답변의 완성을 위해 언급되었습니다. 자세한 내용 은 크레딧이 필요한 다른 답변 을 참조하십시오 ).