실제 상황

실제 상황

다른 프로그램에 대한 입력으로 텍스트를 작성할 때 대상 텍스트에서 큰따옴표 안에 있는 모든 명령 대체가 쉘에 의해 해석되고 확장된다는 것을 발견했습니다.

답변 링크여기매개변수 확장이나 명령 대체를 방지하기 위해 작은따옴표를 사용할 수 있다는 점을 지적합니다. 그러나 명령 대체를 작은따옴표로 묶어도 쉘이 명령 대체를 확장하는 것을 막지는 못한다는 것을 알았습니다.

쉘이 명령 대체를 실행할 명령 대신 텍스트로 해석하는 것을 방지하는 방법은 무엇입니까?

데모

$ echo "`wc -l *`"

현재 디렉터리에 있는 모든 파일의 줄 수를 계산해 보세요.

$ echo "'`wc -l *`'"

결과는 동일합니다. 즉, 현재 디렉터리에 있는 모든 파일의 줄 수를 계산합니다.

고쳐 쓰다이 데모를 보면 작은따옴표로 인용하는 것이 문제인 것 같습니다. `작은따옴표와 (백틱)을 큰따옴표로 묶는 것 같아요문자 그대로의 의미를 유지하세요(즉, 억제) 작은따옴표를 사용하지만 명령 대체를 도입하는 백틱(즉, 백틱)의 문자 그대로의 의미를 유지하지는 않습니다.

내 사용 사례에서는 다른 명령의 입력을 참조해야 합니다. 이것으로문서설명하다:

작은따옴표 안에는 작은따옴표가 포함될 수 없습니다.

작은따옴표 명령 대체가 (큰따옴표) 문자열 안에 있을 때 확장되는 것을 방지하는 방법은 무엇입니까? 백슬래시 이스케이프를 사용하는 것 외에 다른 방법이 있어야 합니다.

실제 상황

프로그램에서 작업 설명을 별도의 줄로 구분하는 데 사용한 유일한 방법은 설명을 큰따옴표로 묶는 것입니다.

$ task add "first line doesn\'t say much
Second line says a lot but part of this line does not appear in the resulting description 'truncate -s0 !(temp_file | temp_dir)' truncates all files to 0 bytes as shown by: '`wc -l *`'"

결과 설명:

first line doesn\ -s0 !(temp_file | temp_dir)' truncates all files to 0 bytes as shown by: 0 file1 10 file2 0 directory1 0 directory2 502 file3 123 file4 162 file5 0 directory3

보시다시피

't say much
Second line says a lot but part of this line does not appear in the resulting description 'truncate

설명에서 누락되었으며 쉘에서 'wc -l *'명령 대체로 해석되어 현재 디렉토리에 있는 모든 파일의 행 번호를 설명의 일부로 포함합니다.

쉘이 task(백슬래시)와 사이의 인수 부분을 제거하는 원인은 무엇이며, 쉘이 위의 작은따옴표 명령 대체(예:)를 해석하지 못하도록 방지하는 방법은 무엇입니까?\-s'`wc -l *`'

답변1

강한 인용을 위해서는 작은따옴표를 사용하세요:

printf '%s\n' '`wc -l *`'

에 전달하는 매개변수에 작은따옴표도 포함하려면 자체에 대해 다른 따옴표를 사용해야 printf합니다 . 예를 들면 다음과 같습니다.'

printf '%s\n' '`wc -l *` and a '"'"' character'

또는:

printf '%s\n' '`wc -l *` and a '\'' character'

다른 대안으로는 `큰따옴표 안에 백슬래시를 사용하는 것이 있습니다.

printf '%s\n' "\`wc -l *\` and a ' character"

또는 `일부 확장의 결과:

backtick='`'
printf '%s\n' "${backtick}wc -l *${backtick} and a ' character"

또한 참고하십시오:

cat << 'EOF'
`wc -l *` and a ' character and a " character
EOF

인용에 대해 걱정하지 않고 임의의 텍스트를 출력합니다(첫 번째 텍스트 주위에 따옴표가 있음 EOF).

다음과 같이 할 수도 있습니다.

var=$(cat << 'EOF'
echo '`wc -l *`'
EOF
)

다음을 사용 ksh93하거나 mksh최적화할 수 있습니다.

var=$(<<'EOF'
echo '`wc -l *`'
EOF
)

(또한 작동 zsh하지만 여전히 cat서브쉘에서 실행됩니다.) $var리터럴을 포함하는 데 사용됩니다 echo '`wc -l *`'.

셸에는 다음 을 포함 fish할 수 있습니다 .''...'\'

printf '%s\n' '`wc -l *` and a \' character'

하지만 `어쨌든 그곳은 특별하지 않습니다.

printf '%s\n' "`wc -l *` and a ' character"

그것도 괜찮습니다.

rc, es 또는 with 안에 다음을 zsh -o rcquotes삽입할 수 있습니다.''...'''

printf '%s\n' '`wc -l *` and a '' character'

바라보다일반 문자처럼 특수 문자를 사용하는 방법은 무엇입니까?자세한 내용은.

답변2

여기에 (개행 추가),

$ task add "first line doesn\'t say much
Second line says a lot but part of this line does not appear in the
resulting description 'truncate -s0 !(temp_file | temp_dir)' truncates
all files to 0 bytes as shown by: '`wc -l *`'"

전체 문자열은 큰따옴표로 묶여 있으므로 명령 대체 및 기타 확장이 여기에서 실행됩니다. 이는 셸에서 발생하므로 task문자열을 보기 전에 백슬래시를 사용하거나 해당 부분을 작은따옴표로 묶어 이를 방지해야 합니다.

예를 들어

$ printf "%s\n" "...shown by: '\`wc -l *\`'"
...shown by: '`wc -l *`'

그래서,

task add "...shown by: '\`wc -l *\`'"

문자열을 ...shown by: '`wc -l *`'에 전달합니다 task. 이는 수행하는 작업에 따라 다릅니다.

백슬래시를 사용하지 않으려면 다음과 같이 작은따옴표로 묶으면 됩니다.

#               aaaaaaaaaaaaaaaaBBBBBBBBBBBaaa
$ printf "%s\n" "...shown by: '"'`wc -l *`'"'"
...shown by: '`wc -l *`'

( a'는 큰 따옴표로 묶인 부분을 표시하고 B'는 작은 따옴표로 묶인 부분을 표시합니다. 이는 단순히 쉘 명령줄에서 연결됩니다. 작은 따옴표로 묶인 리터럴은 큰 따옴표로 묶인 문자열 안에 있습니다.)


작은따옴표와 백슬래시의 경우 큰따옴표 안의 작은따옴표를 이스케이프 처리할 필요가 없습니다. 실제로 백슬래시는 그대로 유지됩니다.

$ printf "%s\n" "foo'bar"
foo'bar
$ printf "%s\n" "foo\'bar"
foo\'bar

표시된 내용에 따르면 task최소한 첫 번째 작은따옴표 문자열이 매개변수에서 제거된 것 같습니다(제거된 부분이 이기 때문에 그 뒤에 단어도 추가됨 't say much ... 'truncate).

이것껍데기~ 할 것이다아니요이렇게 하면 훌륭하게 작동합니다.

$ printf "%s\n" "a 'quoted string' to test"
a 'quoted string' to test

쉘이 (백슬래시)와 task사이의 인수 부분을 제거하는 원인은 무엇입니까?\-s

아마도 이 작업을 수행하는 쉘이 아닐 것입니다.

그리고 쉘이 위의 작은따옴표 명령 대체(예: '`wc -l *`')를 해석하는 것을 방지하는 방법은 무엇입니까?

작은따옴표가 아니라 옆에 작은따옴표가 있는 큰따옴표입니다.

답변3

다음과 같이 백슬래시를 사용하여 백틱을 이스케이프할 수 있습니다.

echo "\`wc -l *\`"

답변4

도망가다어느특수 문자가 처리되지 않고 대체가 수행되지 않도록 하는 임의의 문자 시퀀스:

  1. 각각을 '다음으로 교체하십시오.'\''
  2. 결과 문자열을 작은따옴표로 묶습니다.

예를 들어:

`wc -l 'my file.txt'`

~이 되다

'`wc -l '\''my file.txt'\''`'

문자열이 로 시작하거나 끝나는 경우 '시작/끝에서 끝나게 됩니다. ''이는 아무 작업도 수행하지 않으며 제거할 수 있지만 그대로 두는 것이 유효합니다(예: 문자열을 전치된 상태로 유지합니다. 정의 함수는 간단합니다). .

관련 정보