Bash 스크립트에서 따옴표 없이 변수를 렌더링하는 방법은 무엇입니까?

Bash 스크립트에서 따옴표 없이 변수를 렌더링하는 방법은 무엇입니까?

다음 스크립트:

$ cat runme01.sh 
#!/bin/bash

A=myval
B=$A/{fix}
C=$A/fix

set -xT

echo $B
echo $C

실행하면 다음이 인쇄됩니다.

$ ./runme01.sh 
+ echo 'myval/{fix}'
myval/{fix}
+ echo myval/fix
myval/fix

보시다시피 변수는 B작은따옴표로 전달되고 변수는 작은따옴표 없이 전달됩니다.echoC

아마도 교정기 때문에 그런 것 같습니다.

나는 항상 따옴표 없이 전달하고 싶습니다. 어떻게 하나요?

답변1

추적 출력을 순전히 정보 제공용으로 해석하지 마십시오. 이것은 디버그 출력입니다.

myval/{fix}작은 따옴표 안의 중괄호는 쉘이 특정 문자열을 다른 것으로 해석하는 것 외에는 별 의미가 없다는 것을 보여줍니다 .특히, 그렇습니다아니요문자열이 인용되었다는 뜻입니다! 중괄호가 다음과 같기 때문에 쉘은 추적 출력에 작은따옴표를 추가합니다.때때로그러나 이 경우에는 특별하지 않습니다(실제 버팀대 확장을 사용하지 않기 때문에).

여기서도 같은 일이 발생합니다(빈 디렉터리에서 실행).

$ echo *
+ echo '*'
*

내 명령에 인용문을 사용하지 않으므로 *쉘이노력하다그것을 연장하기 위해. 아무것도 확장되지 않으므로 확장되지 않은 상태로 유지됩니다. 추적 출력을 생성하는 코드는 *문자열의 a를 확인하고 이를 인용합니다.이는 인쇄되는 문자열에 있는 문자를 기반으로 작은따옴표를 기계적으로 추가하는 것을 기반으로 하며 명령이나 결과에 어떤 방식으로든 영향을 주지 않습니다.

이를 다시 설명하면 다음과 같습니다.

$ ls -l
total 0
-rw-r--r--  1 kk  wheel  0 Jun 14 20:15 "filename"
-rw-r--r--  1 kk  wheel  0 Jun 14 20:13 'filename'
-rw-r--r--  1 kk  wheel  0 Jun 14 20:14 *
-rw-r--r--  1 kk  wheel  0 Jun 14 20:14 **
-rw-r--r--  1 kk  wheel  0 Jun 14 20:14 123
-rw-r--r--  1 kk  wheel  0 Jun 14 20:14 file
-rw-r--r--  1 kk  wheel  0 Jun 14 20:14 long name
-rw-r--r--  1 kk  wheel  0 Jun 14 20:14 {}
$ echo *
+ echo '"filename"' ''\''filename'\''' '*' '**' 123 file 'long name' '{}'
"filename" 'filename' * ** 123 file long name {}

즉, 문자열의 특정 문자로 인해 추적 출력을 생성하는 코드가 실패하게 됩니다 bash. 또한 쉘은 문자열에서 작은따옴표를 이스케이프합니다.

이것을 또는 다음과 dash비교하십시오 pdksh.

$ echo *
+ echo "filename" 'filename' * ** 123 file long name {}
"filename" 'filename' * ** 123 file long name {}

이러한 특정 쉘은 따옴표를 추가하지 않습니다(또는 작은 따옴표를 이스케이프 처리합니다). 실제로는 중요하지 않습니다. 단지 디버그 출력일 뿐입니다.


쉘이 문자열에 대해 토큰화 및 파일 이름 생성(globbing)을 수행하도록 명시적으로 원하지 않는 한 항상 큰따옴표로 묶인 변수 확장을 사용하십시오.

큰따옴표가 항상 그런 것은 아닙니다.필요, 그러나 불필요한 문맥을 기억하는 것보다 항상 큰따옴표를 사용하는 것을 기억하는 것이 더 쉽습니다.

스크립트가 수정되었습니다:

#!/bin/bash

A=myval
B="$A/{fix}"
C="$A/fix"

set -xT

printf '%s\n' "$B"
printf '%s\n' "$C"

이렇게 하면 값에 관계없이 항상 이러한 값을 가져와서 $B표준 출력으로 인쇄할 수 있습니다. $C원래 코드에서 $Awas 를 *사용 $B하고 $C따옴표를 사용하지 않으면 일치하는 파일 이름을 가져올 수 있습니다.

추적 출력에서는 여전히 myval/{fix}이 코드를 사용하여 문자열을 인용합니다. 걱정하지 마세요. 이것은 아무 의미도 없습니다. 단지 디버그 출력을 돕기 위한 셸일 뿐입니다.

관련된:

답변2

일단 설정하면 IFS=$'\n'단어 분리가 발생하지 않으며 따옴표 없이 모든 작업을 수행할 수 있습니다.

보안 위험이 있을 수 있지만 내가 아는 한 그것은 API용이므로 어쨌든 bash 스크립트를 사용하지 않을 것입니다.

어떤 사람들은 x나 y에서는 작동하지 않는다고 말하지만 작동합니다.

관련 정보