에 있을 \etc\defaults
때 bash 프롬프트가 작동하기를 원합니다 .PS1
/etc/defaults
저는 이 두 가지 방법을 시도해 보았어요
PS1="$(echo "\w" | sed 's/\//\\/g')"
PS1="$(tmp="\w" && echo ${tmp//\//\\})"
그러나 둘의 결과는 동일합니다 /etc/defaults
.
둘 다 이상하니까
echo $PWD | sed 's/\//\\/g'
tmp=$PWD && echo ${tmp//\//\\}
인쇄 \etc\defaults
.
답변1
슬래시를 백슬래시로 대체하는 것에 대해 어떻게 생각하든 이것은 실제로 흥미로운 인용문 문제입니다. 다른 유사한 구조를 생각해내는 사람.
PS1
포함 하면 $(echo "\w" | sed 's/\//\\/g')
어떻게 되나요 ?첫 번째Bash는 프롬프트 이스케이프를 위해 이를 처리합니다(예 : ) \w
. 기본적으로 좋은 경로 이름에 작동합니다. 하지만 동시에 그것은 하나의 단일 로 바뀌기도 합니다 ... 그래서 당신이 들어가야 할 것은 입니다 . 또는 추가 백슬래시와 마찬가지로 큰따옴표를 사용합니다 .echo "\w"
echo "/etc/defaults"
\\
\
PS1
$(echo "\w" | sed -e 's/\\//\\\\/g')
$(echo "\w" | sed -e "s/\\\\//\\\\\\\\/g")
그렇다면 문제가 있습니다일를 사용하려면 PS1
작은 따옴표로 묶인 문자열이 필요할 수 있습니다. 작은 따옴표를 포함해야 하므로 '\''
다음과 같이 바꿔야 합니다.
PS1='$(echo "\w" | sed -e '\''s/\\//\\\\/g'\'')'
이것은 어색하며 SE 구문 강조 표시가 이를 올바르게 따르지 않는 것 같습니다. '\''
s 사이의 부분을 인용되지 않은 것으로 표시합니다.
하지만... 이를 수행하는 더 좋은 방법이 있습니다.
쉘 명령줄에서 데이터를 직접 텍스트로 대체하는 것은 기본적으로 문제를 일으키기 때문에 이러한 \w
대체는 다소 수상쩍습니다. 경로가 이면 따옴표가 누락되어 /tmp/quote"me
직접 대체됩니다 . echo "/tmp/quote"me"
Bash는 실제로 따옴표를 이스케이프 처리하기 위해 백슬래시를 추가하므로 가 됩니다. 이는 echo "/tmp/quote\"me"
괜찮습니다. 하지만 그래도 심하니까 피하는 게 좋을 것 같아요. 이스케이프가 구문 분석과 일치하지 않으면 매우 합법적인 명령 삽입 문제가 있을 수 있습니다. 예를 들어, 비슷한 echo '\w'
것은아니요경로에 가 포함되어 있으면 "$\
추가 백슬래시가 나타나고 '
.
또한 실행할 함수를 정의하여 프롬프트 자체에서 명령을 숨겨 sed
참조 지옥을 피할 수 있습니다. 그런데 함수 자체가 프롬프트의 일부가 아니어서 작동하지 않기 때문에 여기서 s///
사용해야 합니다 .$PWD
\w
manglepath() {
echo "$PWD" | sed 's/\//\\/g'
}
PS1='$(manglepath)\$ '
${var//pattern/replacement}
실제로 우리는 를 호출하는 대신 확장 기능을 사용할 수 있어야 하며 sed
아마도 다음을 사용해야 할 것입니다.printf
바꾸다echo
:
manglepath() {
printf "%s\n" "${PWD//\//\\}"
}
PS1='$(manglepath)\$ '
답변2
PS1='$(echo "\w" | sed '\''s#/#\\\\#g'\'')'
이로 인해 PS1이 발생합니다.$(echo "\w" | sed 's#/#\\\\#g')