최근에 bash 프롬프트를 조정하기 시작했는데 이스케이프 문자가 어떻게 작동하는지 이해하지 못한다는 사실을 발견했습니다. 나는 다음을 가지고 있습니다 :
PS1="\[$RED\]\342\224\214\342\224\200"
여기에서 문자를 \[
이스케이프 처리 [
하고 \xxx
UTF-8 문자를 이스케이프 처리했습니다. 그러나 다음 줄에서는 이상한 결과가 나타납니다.
PS1+="$([·\$?·!=·0·]·&&·echo·\[$RED\]\342\234\227\·)"
이는 항상 X
프롬프트에 인쇄되지만 첫 번째 프롬프트를 벗어나면 $
명령의 종료 상태가 0이 아닌 경우에만 인쇄됩니다. 왜 그런지 이해가 안 돼요. $(commands)
주어진 결과가 출력되어서는 안되나요 commands
? 이렇게 이스케이프하면 \$()
전체 시퀀스가 이스케이프됩니까, 아니면 달러 기호만 이스케이프됩니까? 탈출하지 않으면 왜 인쇄되지 않습니까 $
? 그냥 인쇄됩니다 X
. $
대괄호에도 동일한 문제가 있습니다. 왜 나는 그것으로부터 도망쳐야 하는가?
나는 이것이 다른 질문에도 적합하다고 생각하지만 프롬프트에서 실제 종료 상태를 인쇄할 수 있는 방법이 있습니까?
답변1
큰따옴표로 묶인 문자열에서는 명령 치환( $(...)
)과 변수 확장( $foo
)을 처리하는데, 달러 기호 앞의 백슬래시가 이를 방지하므로 백슬래시를 제거한다. 이것은 숙제 중에 PS1="$(...)"
또는 PS1="\$(...)"
.
그러나 프롬프트를 인쇄할 때도 동일한 확장이 처리되므로 할당 시 달러 기호를 이스케이프하면 결과에 PS1
이스케이프되지 않은 달러 기호가 나타나며 프롬프트가 인쇄될 때 확장이 발생합니다.
따라서 이스케이프되지 않은 명령 대체를 사용하면 프롬프트가 할당될 때 명령이 한 번만 실행됩니다. 백슬래시를 사용하면 프롬프트가 인쇄될 때마다 실행됩니다.
다음 두 가지를 사용하여 차이점을 쉽게 테스트할 수 있습니다.
PS1="$(date) "
PS1="\$(date) "
이것은 \[
다릅니다. 일반 큰따옴표 문자열이 아닌 프롬프트를 처리할 때만 관련됩니다. 이는 보이는 문자를 인쇄하지 않는 프롬프트 부분을 표시하는 데 사용됩니다. 또한 프롬프트에서만 작동합니다.앞으로확장 기능이 있으므로 PS1='$(echo "\[...\]")'
원하는 대로 작동하지 않을 수도 있습니다.