[unix] 다른 스크립트의 내용으로 사용할 변수를 이스케이프 처리

이 질문은 올바르게 이스케이프 된 문자열 리터럴을 작성하는 방법에 관한 것이 아닙니다 . 스크립트 또는 다른 프로그램에서 직접 소비하기 위해 변수를 이스케이프 처리하는 방법에 관한 관련 질문을 찾을 수 없습니다.

내 목표는 스크립트가 다른 스크립트를 생성 할 수있게하는 것입니다. 생성 된 스크립트의 작업은 다른 컴퓨터 에서 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"`"

printfDejay 솔루션 의 내장 기능 을 사용하도록 수정 :

function esc_vars {
    printf '%q' "$@"
}


답변

var 값을 인용하는 몇 가지 솔루션이 있습니다.

  1. alias
    대부분의 쉘에서 (alias가 사용 가능한 경우) (csh, tcsh 및 아마도 다른 csh는 제외) :

    $ alias qux=bar\'baz
    $ alias qux
    qux='bar'\''baz'

    예, 이것은 sh대시 또는 애쉬와 같은 많은 쉘 에서 작동합니다 .

  2. 또한 대부분의 쉘에서 (csh가 아닌) 다시 설정 하십시오.

    $ qux=bar\'baz
    $ set | grep '^qux='
    qux='bar'\''baz'
  3. 일부 셸에서 조판 (ksh, bash 및 zsh 이상) :

    $ qux=bar\'baz
    $ typeset -p qux
    typeset qux='bar'\''baz'             # this is zsh, quoting style may
                                         # be different for other shells.
  4. 수출
    먼저해야 할 일 :

    export qux=bar\'baz

    그런 다음 사용하십시오 :
    export -p | grep 'qux='
    export -p | grep 'qux='
    export -p qux

  5. 인용
    echo "${qux@Q}"
    echo "${(qq)qux}" 하나에서 4 Q 년대에 #을 사용할 수있다.


답변