사람들은 변수를 사용할 때 큰따옴표로 묶어야 한다고 흔히 말합니다.
아래 예에서는 명령을 변수에 넣고 echo "You can't see me"
실행하여 출력이 You can't see me
. 이것이 궁극적인 목표입니다.
$ cmd="echo \"You can't see me\""
$ echo "$cmd"
echo "You can't see me"
$ $cmd
"You can't see me"
$ "$cmd"
echo "You can't see me": command not found
그래서 $cmd
그것을 실행했는데 내가 갖고 싶지 않은 큰따옴표가 포함되어 있었고 큰따옴표 변수에 대한 조언을 따르면 오류가 발생했습니다.
리소스에는 권장 사항에 예외가 있다고 나와 있지만 권장 사항에도 예외가 있습니까?언제나사용되어야한다?
eval "$cmd"
나는 실행(또는 큰따옴표 없이)하거나 실행 후 출력의 적절한 변환(큰따옴표 없이)을 수행하여 원하는 결과를 얻는 방법을 알고 있지만 $cmd
이 문제를 어떻게 피할 수 있습니까?
답변1
사람들은 종종 이렇게 말합니다.
사실은자원예를 들어...
맹목적으로 "조언"을 따르지 마십시오. 카고 컬트 프로그래밍을 "올바르게" 수행할 수 있는 방법은 없습니다. bash(1) 맨페이지나 표준 사양과 같은 주요 "리소스"가 있습니까?
문자열을 스크립트 조각으로 평가하려면 다음 eval
을 사용해야 합니다.
cmd="echo \"You can't see me\""
eval "$cmd"
따옴표가 없는 변수를 사용하면 해당 확장에서 작은따옴표 또는 큰따옴표와 같은 셸 메타 문자가 있는지 다시 검색하여 다시 분석하지 않고 변수의 문자로만 분할 하고 전역으로 확장합니다( , 또는 문자 IFS
가 포함된 경우 ).*
?
[
cmd="echo \"What's a *? \""
eval "$cmd"
What's a *?
$cmd
"What's a [all the files in your directory] "
마지막 예에서 는 cmd
확장된 후 echo
, "What's
, a
및 로 분할되고 전역적으로 확장된 다음 다른 모든 문자열을 인수로 사용하여 실행되고 공백(및 일부 쉘에서는)과 연결된 표준 출력으로 인쇄됩니다 *?
. 다른 이스케이프 해당 인수에서도 해석됩니다)."
*?
echo
echo
\n