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


54

에 따르면 이 대답 하고 내 자신의 이해, 물결표는 홈 디렉토리로 확장 :

$ 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


3
또한 명령 행에서 프로그램 인수를 제공 할 때 명령 인수에서 --path ~/myfile확장되지만 확장 --path=~/myfile되지 않는 불일치가 있음에 유의하십시오 .
Ángel



이 테마의 변형은 unix.stackexchange.com/questions/279565 입니다.
JdeBP

답변:


45

그 이유는 큰 따옴표 안에 물결표 ~가 특별한 의미가 없기 때문에 문자 그대로 취급됩니다.

POSIX는 이중 인용 을 다음과 같이 정의합니다 .

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

...

응용 프로그램은 큰 따옴표 안에 포함되도록 큰 따옴표 앞에 백 슬래시가 오는 것을 보장해야합니다. 매개 변수 '@'은 큰 따옴표 안에 특별한 의미가 있습니다.

를 제외하고 $, `, \@다른 문자는 따옴표 안에 리터럴 처리됩니다.


9
어떤 경우에는를 사용해야한다고 생각합니다 $HOME.
Seth

11
또는 당신은 단지를 인용 수 없습니다 ~예를 들어,ls -l ~/"My Documents"
앤드류 메디에게

이것은 매우 직관적이지 않습니다. 그들이 이것을 선택한 이유는 무엇입니까? (이 답변은 실제로 이유를 제시하는 것이 아니라 표준을 가리키고 있지만 아마도 표준은 이유를 위해 그런 식으로 작성되었을 것입니다 .)
iconoclast

1
@iconoclast 당신이 정말로 "왜 그들이 이런 식으로 구현되었는지"를 원한다면 대신 Stephane 답변을 읽으십시오 .
Braiam

2
그래서, @iconoclast 이유 입니다 하늘의 파란색은? :) :) :)
Jesse Chisholm

32

틸드 확장 은 POSIX에 의해 다음과 같이 정의됩니다.

"틸드 접두어"는 단어의 시작 부분에 인용되지 않은 <tilde> 문자와 단어에서 첫 번째 인용되지 않은 <slash> 앞에 오는 모든 문자 또는 <가없는 경우 단어의 모든 문자로 구성됩니다. 슬래시>. 할당에서 여러 물결표 접두어를 사용할 수 있습니다. [...] 할당의 <equals-sign> 다음에, 인용되지 않은 <colon> 다음에, 또는 둘 다 사용하십시오. [...] 물결표 접두어의 문자가 인용되지 않으면 <tilde> 다음에 나오는 물결표 접두어의 문자는 사용자 데이터베이스에서 가능한 로그인 이름으로 처리됩니다. [...] 로그인 이름이 null 인 경우 (즉, 물결표 접두사 만 물결표를 포함하는 경우) 물결표 접두사는 변수 HOME 값으로 대체됩니다. HOME을 설정하지 않으면 결과가 지정되지 않습니다. [...]

가장 짧은 대답은 "그런 식으로 정의 되었기 때문"입니다. 접두사에있는 문자를 인용하면 ~확장이 억제됩니다.

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

물결표 확장으로 인한 경로 이름은 필드 분할 및 경로 이름 확장에 의해 변경되지 않도록 인용 된 것처럼 처리됩니다.

경로의 일부에 따옴표가 필요하지만 나머지는 틸드 접두어 인 경우 틸드 확장과 일반 따옴표를 간단하게 결합 할 수 있습니다.

$ cat ~/"file name with spaces"

더 넓은 "왜"에 대해 : 단어 분리를위한 사용이 없기 때문에 ~, 인용을 요구하는 것이 아니라 기본 행동이어야합니다. 인용 할 필요가 없기 때문에, 인용 부호 ~안에 특별한 의미를 부여 하는 것은 불필요한 합병증이 될 것입니다. 물론 역사적 이유는 그것이 바람직하더라도 지금은 바꿀 수 없다는 것을 의미합니다.


이 bash 안내서 에 따르면 공백 분리 전에 물결표 확장이 발생합니다 . 홈 디렉토리에 공백이 있어도 물결표 확장을 안전하게 수행하는 방법이 있습니까? 보통, 당신은 이런 종류의 일을 할 것입니다 "".
Lucretiel

확장은 한 단어입니다. 답에서 인용 된 두 번째 구절을 참조하십시오.
마이클 호머

23

~ Korn 쉘에 추가되고 나중에 POSIX 쉘 스펙에 추가되기 훨씬 전에 C 쉘에서 시작됩니다.

C-shell ~에는 글 로빙 연산자 (예 : 확장하는 것과 같은 루틴으로 확장 *.txt)가 있었으므로 나머지 글 로빙은 큰 따옴표 안에 수행되지 않았습니다.


11

이것이 왜 그런 식으로 디자인되었는지는 대답하지 않지만 $HOME대체해야 할 경우 대신 사용해야 합니다 ~.

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

6
이것은 작동하지 않습니다~otheruser
Johannes Kuhn

2
사실,하지만 당신은 할 수 : 그들을 = ~ otheruser 다음 사용 "을 $ / 일부 / 경로"
혼합한다

1
해결 방법은 변수 및 큰 따옴표로 확장 된 다른 것들과 다르게 ~otheruser취급하는 것이 나쁜 생각임을 보여줍니다 ~.
iconoclast
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.