큰따옴표 안에서 물결표(~)가 확장되지 않는 이유는 무엇입니까?

큰따옴표 안에서 물결표(~)가 확장되지 않는 이유는 무엇입니까?

~에 따르면이 답변내 자신의 이해에 따르면 물결표는 홈 디렉토리로 확장됩니다.

$ echo ~
/home/braiam

이제 쉘 확장이 작동하기를 원할 때마다(예: 와 같은 변수 이름을 사용하고 $FOO예기치 않은 문자, 공백 등으로 인해 중단되지 않음) 큰따옴표를 사용해야 합니다 ".

$ FOO="some string with spaces"
$ BAR="echo $FOO"
$ echo $BAR
echo some string with spaces

이 확장 프로그램이 물결표와 함께 작동하지 않는 이유는 무엇입니까?

$ echo ~/some/path
/home/braiam/some/path
$ echo "~/some/path"
~/some/path

답변1

그 이유는 큰따옴표 안의 물결표는 ~특별한 의미가 없으므로 리터럴로 처리되기 때문입니다.

POSIX 정의큰따옴표처럼:

큰따옴표( "" )로 묶인 문자는 달러 기호, 백틱 및 백슬래시 문자를 제외하고 큰따옴표 안의 모든 문자의 리터럴 값을 유지합니다.

...

응용 프로그램에서는 큰따옴표 앞에 백슬래시가 있고 그 안에 큰따옴표가 있는지 확인해야 합니다. 매개변수 "@"는 큰따옴표 안에서 특별한 의미를 갖습니다.

$및 이외의 문자 는 큰따옴표 안의 리터럴로 처리 `됩니다 .\@

답변2

물결표 확장POSIX는 다음과 같이 정의됩니다.

"물결표 접두사"는 다음과 같이 지정됩니다.인용되지 않음단어 시작 부분의 <물결표> 문자, 단어에서 따옴표가 없는 첫 번째 <슬래시> 앞의 모든 문자 또는 <슬래시>가 없는 경우 단어의 모든 문자. 할당에서 여러 개의 물결표 접두사를 사용할 수 있습니다. 할당의 <등호> 뒤에 [...], 따옴표가 없는 <콜론> 또는 둘 다. [...] 물결표 접두어의 문자가 인용되지 않은 경우 <물결표> 뒤의 물결표 접두어 문자는 사용자 데이터베이스에서 가능한 로그인으로 처리됩니다. [...] 로그인 이름이 비어 있는 경우(즉, 물결표 접두사에 물결표만 포함된 경우) 물결표 접두사는 HOME 변수의 값으로 대체됩니다. HOME이 설정되지 않은 경우 결과는 지정되지 않습니다. [...]

따라서 가장 짧은 대답은 "그렇게 정의되었기 때문입니다"입니다. 인용 접두사( ~, 포함)의 모든 문자는 확장을 억제합니다.

또한 항상 단일 단어를 생성하도록 확장을 정의하므로 인용이 필요하지 않습니다.

물결표 확장으로 생성된 경로 이름은 필드 분할 및 경로 이름 확장으로 인해 변경되는 것을 방지하기 위해 따옴표로 처리해야 합니다.

일부 경로에 따옴표가 필요하지만 나머지 경로에는 물결표 접두사가 붙는 경우 물결표 확장과 일반 인용을 직접 결합할 수 있습니다.

$ cat ~/"file name with spaces"

더 넓은 "이유"와 관련하여: 단어 분할에는 어떤 용도로도 사용할 수 없으므로 ~인용을 요구하기보다는 이것이 기본 동작이어야 합니다. 인용할 필요가 없기 때문에 ~인용문 안에 특별한 의미를 부여하는 것은 불필요하게 복잡해집니다. 물론 역사적 이유 때문에 이것이 바람직하더라도 지금은 변경할 수 없습니다.

답변3

~Korn 쉘에 추가되고 나중에 POSIX 쉘 사양에 추가되기 오래 전에 C 쉘에서 유래되었습니다.

C-셸에서 는 와일드카드이므로(예: ~확장과 동일한 루틴으로 확장됨) 와일드카드의 나머지 부분은 큰따옴표 내에서 실행되지 않습니다.*.txt

답변4

이것이 왜 이런 방식으로 설계되었는지에 대한 답은 아니지만, $HOME교체가 필요한 경우 이를 사용할 수 있습니다. 왜냐하면 이것이 본질적으로 ~하는 일이기 때문입니다.

$ echo "$HOME/some/path"
/home/braiam/some/path

관련 정보