이 질문은 올바르게 이스케이프 된 문자열 리터럴을 작성하는 방법에 관한 것이 아닙니다 . 스크립트 또는 다른 프로그램에서 직접 소비하기 위해 변수를 이스케이프 처리하는 방법에 관한 관련 질문을 찾을 수 없습니다.
내 목표는 스크립트가 다른 스크립트를 생성 할 수있게하는 것입니다. 생성 된 스크립트의 작업은 다른 컴퓨터 에서 0에서 n 번 까지 실행 되며 생성 된 데이터는 실행되기 전에 변경 될 수 있으므로 네트워크를 통해 직접 작업을 수행하기 때문입니다. 작동하지.
같은 작은 따옴표와 같은 특수 문자를 포함 할 수 있습니다 알려진 변수를 감안할 때, 나는 예를 들어 변수 완전히 탈출 문자열 리터럴로 그를 쓸 필요가 foo
포함 bar'baz
생성 된 스크립트로 표시되어야합니다 :
qux='bar'\''baz'
"qux=$foo_esc"
스크립트의 다른 줄 에 추가 하여 작성합니다 . 나는 Perl을 다음과 같이 사용했다.
foo_esc="'`perl -pe 's/('\'')/\\1\\\\\\1\\1/g' <<<"$foo"`'"
그러나 이것은 과도한 것으로 보입니다.
나는 bash만으로는 성공하지 못했습니다. 나는 이것들의 많은 변형을 시도했다.
foo_esc="'${file//\'/\'\\\'\'}'"
foo_esc="'${file//\'/'\\''}'"
그러나 추가 슬래시가 출력에 나타나거나 (내가 할 때 echo "$foo"
) 구문 오류가 발생합니다 (쉘에서 수행하면 추가 입력이 예상 됨).
답변
Bash에는 정확히이 경우에 대한 매개 변수 확장 옵션이 있습니다 .
${parameter@Q}
확장은 입력으로 재사용 할 수있는 형식으로 인용 된 매개 변수 의 값인 문자열입니다 .
따라서이 경우 :
foo_esc="${foo@Q}"
이것은 Bash 4.4 이상에서 지원됩니다. 다른 형식의 확장 및 전체 지정 문 ( @A
) 을 구체적으로 생성하기위한 여러 옵션이 있습니다 .
답변
Bash는 printf
내장 된 %q
형식 지정자를 제공 합니다.이 지정자는 구형 (<4.0) 버전의 Bash에서도 쉘 이스케이프를 수행합니다.
printf '[%q]\n' "Ne'er do well"
# Prints [Ne\'er\ do\ well]
printf '[%q]\n' 'Sneaky injection $( whoami ) `ls /root`'
# Prints [Sneaky\ injection\ \$\(\ whoami\ \)\ \`ls\ /root\`]
이 트릭은 함수에서 데이터 배열을 반환하는 데 사용될 수도 있습니다.
function getData()
{
printf '%q ' "He'll say hi" 'or `whoami`' 'and then $( byebye )'
}
declare -a DATA="( $( getData ) )"
printf 'DATA: [%q]\n' "${DATA[@]}"
# Prints:
# DATA: [He\'ll\ say\ hi]
# DATA: [or\ \`whoami\`]
# DATA: [and\ then\ \$\(\ byebye\ \)]
Bash printf
내장 기능은 printf
대부분의 Unix 계열 운영 체제와 함께 제공되는 유틸리티와 다릅니다 . 어떤 이유로 printf
명령이 내장 대신 유틸리티를 호출하는 경우 항상 builtin printf
대신 실행할 수 있습니다 .
답변
RTFM이 아닌 것 같습니다. 그렇게 할 수 있습니다 :
q_mid=\'\\\'\'
foo_esc="'${foo//\'/$q_mid}'"
그런 다음 echo "$foo_esc"
예상'bar'\''baz'
실제로 그것을 사용하는 방법은 함수입니다.
function esc_var {
local mid_q=\'\\\'\'
printf '%s' "'${1//\'/$mid_q}'"
}
...
foo_esc="`esc_var "$foo"`"
printf
Dejay 솔루션 의 내장 기능 을 사용하도록 수정 :
function esc_vars {
printf '%q' "$@"
}
답변
var 값을 인용하는 몇 가지 솔루션이 있습니다.
-
alias
대부분의 쉘에서 (alias가 사용 가능한 경우) (csh, tcsh 및 아마도 다른 csh는 제외) :$ alias qux=bar\'baz $ alias qux qux='bar'\''baz'
예, 이것은
sh
대시 또는 애쉬와 같은 많은 쉘 에서 작동합니다 . -
또한 대부분의 쉘에서 (csh가 아닌) 다시 설정 하십시오.
$ qux=bar\'baz $ set | grep '^qux=' qux='bar'\''baz'
-
일부 셸에서 조판 (ksh, bash 및 zsh 이상) :
$ qux=bar\'baz $ typeset -p qux typeset qux='bar'\''baz' # this is zsh, quoting style may # be different for other shells.
-
수출
먼저해야 할 일 :export qux=bar\'baz
그런 다음 사용하십시오 :
kshexport -p | grep 'qux='
bashexport -p | grep 'qux='
zshexport -p qux
-
인용
bash는echo "${qux@Q}"
zsh을echo "${(qq)qux}"
하나에서 4 Q 년대에 #을 사용할 수있다.