변수에서 큰따옴표를 이스케이프하세요

변수에서 큰따옴표를 이스케이프하세요

나중에 실행할 수 있도록 이 명령을 파일에 저장하고 싶습니다.

ln -s "$xr"/ya.txt ~

(1)을 사용하여 이 작업을 수행할 수 있습니다.

cat > zu.sh <<eof
ln -s "$xr"/ya.txt ~
eof

또는 (2):

printf 'ln -s "%s"/ya.txt ~\n' "$xr" > zu.sh

또는 (3):

echo "ln -s '$xr'/ya.txt ~" > zu.sh

또는 (4):

printf 'ln -s %q/ya.txt ~\n' "$xr" > zu.sh

또는 (5):

printf 'ln -s "%s"/ya.txt ~\n' "${xr//\"/\\\"}"

그러나 모든 솔루션에는 문제가 있습니다. (1) 또는 (2)의 변수에 큰따옴표가 포함되어 있으면 실패하고, (3)의 변수에 작은따옴표가 포함되어 있으면 실패합니다. (4) 좋지만 그렇지는 않다POSIX에 의해 정의됨. (5) 아주 좋지만, 하지만 바시즘. 가장 좋은 옵션은 (1) 또는 (2)를 사용하고 변수의 큰따옴표를 이스케이프 처리하는 것 같지만 다른 방법으로 수행할 수 있습니까?

답변1

나는 이것이 안전하다고 생각합니다:

esc() {
    printf "%s\n" "$1" | sed -e "s/'/'\"'\"'/g" -e "1s/^/'/" -e "\$s/\$/'/"
}

그것작은따옴표로 묶인 문자열이므로 입력 문자열의 $, `, \및 는 "중요하지 않습니다., 기존 '문자를 다음으로 변환합니다 '"'"'(예: 끝 작은따옴표, 큰따옴표, 작은따옴표만 사용한 다음 다시 작은따옴표).

매우 사용하고 싶습니다$(...)명령 대체단, 입력에서 후행 개행 문자를 먹는 경우는 제외됩니다. 대신 두 번째와 세 번째 따옴표는 여는 따옴표와 닫는 따옴표를 삽입합니다.sed첫 번째 줄의 시작 부분과 마지막 줄의 끝 부분에 있는 스크립트 자체입니다. 포함된 줄 바꿈은 원래 상태로 유지되므로 괜찮습니다.

출력은 내가 고안할 수 있는 가장 병리적인 경우에도 쉘로 다시 복사하는 데 적합합니다(사용배쉬 ANSI-C 인용문$'...'테스트 문자열을 먼저 생성하고 나중에는 생성하지 않음):

bash-4.4$ esc $'abc\ndef ghi\'jkl$mno`pqr\\stu\\\'vwx\n\n\n'
'abc
def ghi'"'"'jkl$mno`pqr\stu\'"'"'vwx


'
bash-4.4$ echo 'abc
> def ghi'"'"'jkl$mno`pqr\stu\'"'"'vwx
>
>
> '
abc
def ghi'jkl$mno`pqr\stu\'vwx



bash-4.4$ dash
$ echo 'abc
def ghi'"'"'jkl$mno`pqr\stu\'"'"'vwx


'> > > >
abc
def ghi'jkl$mno`pqr\stu\'vwx



$

변수에 넣은 xr=$(esc "$xr")다음 여기 문서나 다른 곳에서 일반적인 대체에 사용하는 것이 안전합니다.

관련 정보