가끔은 스크립트 텍스트를 인용의 이러한 여러 가지 방법을 모두 사용 참조 : "..."
, '...'
, $'...'
,와 $"..."
. 왜 이렇게 많은 종류의 인용문이 사용됩니까?
그것들은 다르게 행동하거나 내가 그들 안에서 할 수있는 일에 영향을 줍니까?
가끔은 스크립트 텍스트를 인용의 이러한 여러 가지 방법을 모두 사용 참조 : "..."
, '...'
, $'...'
,와 $"..."
. 왜 이렇게 많은 종류의 인용문이 사용됩니까?
그것들은 다르게 행동하거나 내가 그들 안에서 할 수있는 일에 영향을 줍니까?
답변:
이것들은 모두 다른 것을 의미하며, 그 안에 다른 것을 쓸 수 있습니다 (또는 다른 의미로 같은 것을). 다른 종류의 따옴표는 내부의 다른 이스케이프 시퀀스를 해석 \something
하거나 ( $something
) 변수 보간 ( ) 및 다른 종류의 확장을 허용하거나 허용하지 않습니다 .
한마디로 :
'...'
완전히 문자 그대로입니다."..."
변수와 포함 된 따옴표를 모두 허용합니다. $'...'
와 같은 문자 이스케이프를 수행 \n
하지만 변수를 확장하지는 않습니다.$"..."
Bash와 ksh의 인간 언어 번역을위한 것입니다.작은 따옴표 사이에 쓴 내용은 그대로 처리되며 전혀 처리되지 않습니다. 백 슬래시와 달러 기호는 특별한 의미가 없습니다. 즉, 문자 (다른 작은 따옴표 포함)를 백 슬래시 이스케이프하거나 변수를 보간하거나 다른 쉘 기능을 사용할 수 없습니다.
이 모든 예제는 말 그대로 인용 부호 사이에 쓰여진 내용을 나타냅니다.
'hello world' => hello world
'/pkg/bin:$PATH' => /pkg/bin:$PATH
'hello\nworld' => hello\nworld
'`echo abc`' => `echo abc`
'I\'dn\'t've' => I\dn'tve
마지막 하나는 복잡합니다- 작은 따옴표로 묶인 두 개의 문자열이 따옴표없는 텍스트와 함께 실행됩니다. 첫 번째는을 포함 I\
합니다. 따옴표없는 텍스트 dn\'t
에는 쉘 수준에서 이스케이프 된 작은 따옴표 가 포함되어 있으므로 따옴표로 묶인 문자열을 시작하지 않고 리터럴 문자 ()로 포함됩니다 dn't
. 마지막으로 인용 된 문자열은 ve
입니다. 그것들은 쉘이 작동하는 일반적인 방식으로 단일 단어로 함께 실행됩니다.
리터럴 텍스트와 변수를 결합하는 다소 일반적인 관용구는 다음과 같이 함께 실행하는 것입니다.
'let x="'$PATH\"
결과
let x="/usr/bin:/bin"
단일 단어로 ( 변수 값 의 공백이나 글러브 문자는 달리 처리 될 수$PATH
있는 경우를 대비 하여 큰 따옴표 로 묶는 것이 좋습니다. 하지만 읽을 수있는 실행 예제를 위해 나는하지 않았습니다).
큰 따옴표 안에는 두 종류의 확장이 처리되며 백 슬래시를 사용하여 확장 또는 이스케이프가 처리되지 않도록 문자를 이스케이프 처리 할 수 있습니다.
큰 따옴표 안에는 두 가지 범주의 확장이 있습니다.
$
( 파라미터 확장 $abc
하고${abc}
, 명령 치환$(...)
및 산술 확장$((...))
);`abc`
;인용 부호 안에 백 슬래시는 $
또는 앞에 확장을 사용하여 이러한 확장을 막을 수 있습니다 `
. 또한 닫는 큰 따옴표를 피할 수 있으므로 문자열 또는 다른 백 슬래시 \"
에만 포함 "
하십시오. 다른 백 슬래시는 문자 그대로 유지됩니다. 다른 문자를 생성하기위한 이스케이프가 없으며 제거되지 않습니다.
이러한 예 중 일부는 이전과 다르게 작동하지만 일부는 그렇지 않습니다.
"hello world" => hello world
"/pkg/bin:$PATH" => /pkg/bin:/bin:/usr/bin
"hello\nworld" => hello\nworld
"hello\\nworld" => hello\nworld
"`echo abc`" => abc
"I\'dn\'t've" => I\'dn\'t've
"I'dn't've" => I'dn't've
"I\"dn\"t've" => I"dn"t've
이러한 종류의 인용을 통해 C 스타일 백 슬래시 이스케이프를 처리 할 수 있지만 포함 된 변수 나 대체 는 할 수 없습니다 . 문자 이스케이프를 지원 하는 유일한 인용 부호 입니다.
이것은 ksh의 확장으로, 이제 Bash, zsh 및 기타 셸에서도 지원됩니다. 그것은 아닙니다 아직 POSIX 표준과 사용하지 수 있도록 최대한 휴대용 스크립트의 일부하지만 배쉬 또는 ksh 스크립트는 무료입니다.
이러한 이스케이프들은 모두 C의 의미와 함께 사용할 수 있습니다 \a
, \b
, \f
, \n
, \r
, \t
, \v
, 및 리터럴 탈출 \\
, \'
, \"
,와 \?
. 또한 확장 \e
(이스케이프 문자) 및 Bash 및 ksh \cx
( Ctrl-x 로 입력 되는 것 , 예를 들어 \cM
캐리지 리턴)를 지원합니다. 쉘에는 자체적으로 작은 확장 기능이 있습니다.
또한 네 가지 종류의 일반 문자 이스케이프를 허용합니다.
\nnn
8 진수 값이 nnn 인 단일 바이트\xHH
16 진 값 HH를 갖는 단일 바이트\uHHHH
, 16 진 색인이 HHHH 인 유니 코드 코드 포인트\UHHHHHHHH
16 진 인덱스가 HHHHHHHH 인 유니 코드 코드 포인트이 숫자는 모두 첫 번째 숫자 다음에 선택 사항입니다.
$
그리고 `
아무런 의미가 없으며 그대로 보존되어 있습니다, 그래서 당신은 거기에 변수를 포함 할 수 없습니다.
$'hello world' => hello world
$'/pkg/bin:$PATH' => /pkg/bin:$PATH
$'hello\nworld' => hello
world
$'`echo abc`' => `echo abc`
$'I\'dn\'t\'ve' => I'dn't've
$'\U1f574\u263A' => 🕴☺
이러한 이스케이프의 대부분은 당신이 사용하여 시뮬레이션 할 수 있습니다 명령을 POSIX는 필요하지만, , , , , , , , , 그리고 이 일을 할 수 있습니다. 필요한 경우 명령 대체를 사용하여 큰 따옴표 안에 넣을 수 있습니다 .printf
\\
\a
\b
\f
\n
\r
\t
\v
\nnn
printf
"Path:$(printf '\t')$PATH"
이것은 자연어 텍스트 문자열을 지역화하기위한 ksh 및 Bash 별 확장이며 메시지 카탈로그에서 따옴표 안의 부분을 찾습니다. 모든 큰 따옴표 확장을 먼저 수행합니다. 번역 데이터베이스에서 문자열을 찾을 수없는 경우 자체 번역으로 사용됩니다. 내장 가정은 문자열이 영어로되어 있다는 것입니다.
당신은 아마 이것을 사용하고 싶지 않을 것입니다, 그러나 당신이 그것을 보면 일반적으로 큰 따옴표로 처리 할 수 있습니다.
한 가지 주목할 점은 내장 된 매개 변수 확장과 내장 된 문자 이스케이프를 모두 허용하는 인용 은 없습니다 . 대부분의 경우 원하는 경우 다음을 사용하는 것이 좋습니다 printf
.
printf 'New path: \e[1m%s\e[0m' "/pkg/bin:$PATH:"
이것은 문자 이스케이프가 적용되는 부분과 데이터 값인 부분을 명확하게 구분합니다.
다른 인용 부호는 배열 인용 부호가 큰 따옴표 안에 사용 되지 않는 한 이러한 모든 인용 스타일이 쉘에서 단일 "단어"를 생성한다는 것 입니다. 작은 따옴표 형식은 항상 한 단어이며 더 이상 확장되지 않습니다.$@
${x[@]}
$"..."
2.0에서 bash에 추가 된 ksh93에서 가져온 것입니다.
\cX
에가 zsh
. 그것은 \CX
또는 \C-X
거기에 있습니다 ( \c
이미 특별한 의미가 있습니다 echo
)
'let x="'$PATH\"
이외의 다른 셸의 목록 상황에서 잘못된 zsh
으로 $PATH
인용되지 않은 (그래서 당신이 여기 싶지 않을 것이다 + 글로브을 분할의 대상이 될 것이다).