배쉬 매뉴얼에서
set -x
명령, 대소문자, 선택 및 산술 명령과 해당 인수 또는 관련 단어 목록을 포함한 간단한 명령의 추적을 인쇄합니다.확장 후 실행 전. PS4 변수의 값이 확장되고 결과 값이 명령 및 확장된 인수 앞에 인쇄됩니다.
그러나 인쇄된 흔적은 정확히 확장 후의 결과가 아니라 실행 전의 결과라는 것을 알았습니다. 특히, 추적은 따옴표가 제거된 후에 이루어져야 하지만 출력물에는 추가 따옴표나 백슬래시가 추가되어 있습니다. 이는 마치 원래 명령을 실행한 것과 동일한 결과를 얻기 위해 셸에서 명령으로 출력물을 실행할 수 있는 것처럼 보입니다. 왜 그런 겁니까?
그렇다면 확장 후 실행 전의 실제 중간 해석 결과를 추적 출력에서 어떻게 추론할 수 있습니까?
예를 들어 unset 의 var
경우
$ echo '$var'
+ echo '$var'
$var
$ echo "$var"
+ echo ''
$ echo \$var
+ echo '$var'
$var
$ echo \'$var\' # why is the trace print out not: echo \'\'
+ echo ''\'''\'''
''
$ echo \'
+ echo \'
'
$ echo "'" # why is the trace print out not: echo "'"
+ echo \'
'
$ echo "''" # why is the trace print out not: echo "''"
+ echo ''\'''\'''
''
$ echo \'\' # why is the trace print out not: echo \'\'
+ echo ''\'''\'''
''
$ echo \\ # why is the trace print out not: echo \\
+ echo '\'
\
답변1
매뉴얼 인용 :
확장 후 실행 전
귀하는 다음과 같이 주장합니다.
그러나 인쇄된 흔적은 정확히 확장 후의 결과가 아니라 실행 전의 결과라는 것을 알았습니다.
하지만 그들은 그렇습니다. 확장 결과는단어 목록. Bash는 따옴표를 사용하여 단어 목록을 명확하게 표현합니다. bash가 인쇄하는 것은 따옴표를 제거하지 않은 확장의 중간 결과가 아닙니다. 그것은인쇄된 표현문자열 목록입니다.
예를 들어 추적이 다음과 같은 경우
+ cp foo bar qux
그러면 명령이 cp
3개의 인수 foo
, bar
and 를 취했는지 qux
, 2개의 인수 foo bar
and를 취했는지 qux
(예를 들어 원래 명령이 였기 때문에 cp "foo bar" qux
), 2개의 인수 foo
and 를 취했는지 bar qux
, 실제로 이름이 붙은 명령인지 cp foo bar qux
등을 알 수 있는 방법이 없습니다. 추적을 명확하게 하기 위해 bash는 따옴표를 사용합니다. 팔로우할 인용문을 선택하세요.가능한 방법Bash 스크립트에서 이 명령을 실행하세요.
예를 들어, 추적은 + echo '$var'
명령이 echo
하나의 인수(4자 문자열)로 실행되었음을 나타냅니다 $var
. 이 명령을 실행하는 방법에는 여러 가지가 있습니다. 예를 들면 다음과 같습니다.
echo '$var'
echo \$var
echo \$\v\a\r
echo "\$v"\a''''r
echo "$a" # after running a='$var'
답변2
추적에서는 가능하면 강한 따옴표를 사용하는 것으로 보입니다. 추측해야 한다면 다음 예와 같이 쉘 환경 변수의 변경에 관계없이 결과를 쉽게 재현할 수 있을 것입니다.
$ echo '$var'
+ echo '$var'
$var
큰 따옴표는 다음과 같이 "더 간단한"(즉, 이스케이프되지 않은) 복사를 허용하는 것 같습니다.
$ echo \\ # why is the trace print out not: echo \\
+ echo '\'
\
그러나 '
s를 복사할 때는 강한 따옴표를 선택하므로 이스케이프해야 합니다. 약한 따옴표를 사용할지 강한 따옴표를 사용할지 고민하는 것보다 이것이 더 간단하다고 생각합니다. 이는 엣지 케이스 확인을 혼란스럽게 할 수 있습니다.