~는 항상 $ HOME과 같습니까?


40

나는 이것이 이전에 요청되었을 것이라는 것을 알고 있지만 Google에서는 찾을 수 없었습니다.

주어진

  • 리눅스 커널
  • $ HOME을 변경하는 구성이 없습니다.
  • 세게 때리다

~ == $HOME사실?


3
나는 그렇게 생각하지만 이것은 Linux 관련 문제가 아닙니다. 오히려, 나는 POSIX 환경 ~과 동등한 것으로 생각 $HOME합니다. 그러나 나는 틀릴 수 있었다.
HalosGhost

4
아래 답변에도 불구하고 ... 항상 그런 것은 아닙니다. echo "~"와 비교하십시오 echo "$HOME".
Sparhawk

@Sparhawk 잠깐만 요, 1 + 1 2 가 아니 십니까? 음모입니다! 정부는 우리에게 무언가를 숨기고 있습니다! : P
Doorknob

1
@Sparhawk, 당신은 영업 이익이 실제로 중 하나를 인용하지 않았다 알 수 있습니다 ~또는 $HOME. : P
HalosGhost

2
@HalosGhost 아, 좋은 지적입니다. (나중에 나는 마이클 호머의 대답에 "인용되지 않은 단일 인용구 ~"가 언급되어 있음을 알게 되었다.
Sparhawk

답변:


46

이해해야 할 것은 ~확장은 (일부 쉘의) 쉘의 기능이며, 그것이 사용되는 곳의 홈 디렉토리를 의미하는 것보다 마술이 아닙니다.

$var명령이 실행되기 전에 쉘 명령 행에서 사용될 때 일부 조건에서는 값이 확장되는 것처럼 (명령 행을 해석하는 데 사용되는 응용 프로그램 인 쉘에 의해) 확장됩니다.

이 기능은 1970 년대 후반에 C- 쉘에 처음 나타 났으며 (Bourne 쉘에는 없었거나 이전의 Thompson 쉘도 없었습니다), 나중에 Korn 쉘에 추가되었습니다. 80 년대). 결국 POSIX에 의해 표준화되었으며 현재 POSIX가 아닌 것을 포함하여 대부분의 쉘에서 사용할 수 있습니다 fish.

쉘에서 널리 사용되기 때문에 일부 비쉘 응용 프로그램은이를 홈 디렉토리를 의미하는 것으로 인식합니다. 즉, 설정 파일 또는 많은 응용 프로그램의 경우의 자신의 명령 행 ( mutt, slrn, vim...).

bash특히 (GNU 프로젝트의 쉘이며 많은 Linux 기반 운영 체제에서 널리 사용됨)은로 호출 될 때 sh주로 확장에 대한 POSIX 규칙을 따르며 POSIX~의해 지정되지 않은 영역에서는 대부분 Korn 쉘과 유사하게 작동합니다. 그것은 부분 복제입니다).

$var대부분의 장소에서 확장 되지만 (작은 따옴표 제외), ~확장은 나중에 특정 조건에서만 확장됩니다.

문자열이 예상되는 컨텍스트에서 목록 컨텍스트에서 자체 인수에있을 때 확장됩니다.

다음은 확장 된 위치의 몇 가지 예입니다 bash.

  • cmd arg ~ other arg
  • var=~
  • var=x:~:x(POSIX에 필요하며 PATH, MANPATH... 와 같은 변수에 사용됨 )
  • for i in ~
  • [[ ~ = text ]]
  • [[ text = ~ ]]( ~AT & T에서는 패턴으로 채택 ksh되었지만 bash4.0 이후 로 는 확대 되지 않았습니다 ).
  • case ~ in ~) ...
  • ${var#~} (다른 껍질에는 없지만)
  • cmd foo=~(로 호출 될 때가 sh아니라 왼쪽에있는 =것이 인용되지 않은 bash변수 이름 과 같은 모양 일 때만 )
  • cmd ~/x (물론 POSIX에 필요)
  • cmd ~:x(하지만 x:~:xx-~-x)
  • a[~]=foo; echo "${a[~]} $((a[~]))" (다른 껍질에는 없음)

다음은 확장되지 않은 몇 가지 예입니다.

  • echo "~" '~'
  • echo ~@ ~~(또한 ~uuser의 홈 디렉토리로 확장되도록되어 있음 u).
  • echo @~
  • (( HOME == ~ )), $(( var + ~ ))
  • with extglob: case $var in @(~|other))...( case $var in ~|other)괜찮아도).
  • ./configure --prefix=~( --prefix유효한 변수 이름이 아니기 때문에)
  • cmd "foo"=~(에서 bash따옴표 때문에).
  • sh다음 export "foo"=~과 같이 호출 될 때 : , env JAVA_HOME=~ cmd...

확장 대상 : ~단독으로 HOME변수 의 컨텐츠 또는 설정되지 않은 경우 계정 데이터베이스에있는 현재 사용자의 홈 디렉토리로 확장합니다 (POSIX가 해당 동작을 정의하지 않은 확장으로).

ksh88 및 bash4.0 이전 버전에서 물결표 확장은 목록 컨텍스트에서 globbing (파일 이름 생성)을 수행했습니다.

$ bash -c 'echo "$HOME"'
/home/***stephane***
$ bash -c 'echo ~'
/home/***stephane*** /home/stephane
$ bash -c 'echo "~"'
~

일반적인 경우에는 문제가되지 않습니다.

확장되었으므로 다른 확장 형식과 동일한 경고가 적용됩니다.

cd ~

구성 요소로 $HOME시작 -하거나 ..구성 요소를 포함하는 경우 작동하지 않습니다 . 따라서 엄밀히 말하면 차이를 만들 가능성은 거의 없지만 다음과 같이 작성해야합니다.

cd -P -- ~

또는:

case ~ in
  (/*) cd -P ~;;
  (*) d=~; cd -P "./$d";;
esac

(의 값을 포함하는 $HOME-, +2또는 단순히 ...)

cd

( cd인수없이 홈 디렉토리로 이동)

다른 쉘에는보다 고급 ~확장 기능이 있습니다. 예를 들어에 zsh다음이 있습니다.

  • ~4, ~-, ~-2(완료와 함께) 디렉토리 스택의 디렉토리 (당신이했던 장소 확장하는 데 사용 cd이전에를).
  • 동적 명명 된 디렉토리 . ~something확장 방법을 결정하는 고유 한 메커니즘을 정의 할 수 있습니다 .

25

모든 시스템의 모든 Bash 버전에서 yes 입니다. ~자체 용어는 다음과 같이 확장되도록 정의됩니다.

$ HOME의 가치

따라서 항상 $HOME현재 쉘에 있는 것과 동일 합니다. 이 같은 여러 가지 다른 물결표 확장입니다 ~user대한 user의 홈 디렉토리는하지만, 단일 인용 부호로 둘러싸이지 않은 ~자체는 항상로 확장됩니다 "$HOME".

주의 행동~그리고 $HOME경우에 따라서 다를 수있다 : 특히, 경우이 $HOME공간 (또는 다른 포함 IFS의 문자), 다음 $HOME동안 (인용 부호로 둘러싸이지 않은)는 여러 단어로 확장됩니다 ~항상 하나의 단어입니다. (따옴표) ~와 동일하게 확장됩니다 "$HOME".

특정 질문과 관련하여 :

[[ $HOME == ~ ]]

단어 분리를 [[ 억제 하기 때문에 항상 참 입니다. 패턴 일치 문자 가 [[ ~ == $HOME ]있는 경우 HOME는 아니지만 (즉, quoted )는 항상 참입니다. 공백이나 특수 문자 를 포함하는 값의 경우 단일 괄호 안에 사용하면 구문 오류가 될 수 있습니다 . 어떤 재치있는 홈 디렉토리 구성의 경우 와 동일하며, 동일로 비교합니다.[[ ~ == "$HOME" ]]"$HOME"HOME~"$HOME"


스테판 Chazelas가이 코멘트의 경우 지적했다 ~$HOME다른 값을 줄을 다음과 같은 경우에 unset HOME사용할 때, 다음 ~배쉬는 호출 getpwuid암호 데이터베이스의 값을 읽을 수 있습니다. 이 경우는 구성을 변경하지 않는 조건에서 제외 $HOME되지만 여기서는 완전성을 위해 언급하겠습니다.


1
그러나 /bin/sh아닐 수도 있습니다 bash. Posix sh사양에 대해 잘 모르겠습니다~
Basile Starynkevitch

1
POSIX는를 지정합니다 ~. ~Thomson 또는 Bourne 쉘에 없었습니다 (그 당시는로 사용할 수있었습니다 /bin/sh). 그것은 rc또는 그것의 파생물 (다른 것에 사용되는 곳)에 없습니다
Stéphane Chazelas

5
를 포함하여 일부 쉘에서 설정되지 않은 bash경우 passwd 데이터베이스에서 사용자의 홈 디렉토리로 확장됩니다. 따라서 의 값으로 확장되지 않을 수 있습니다 . HOME~~$HOME
Stéphane Chazelas

1
참고 bashbash4는 틸드 확장 (시도에 globbing을 수행하는 데 사용하기 전에 HOME='/*' bash -c 'echo /*'). 따라서 HOME=/*; [ "$HOME" = ~ ]오류가 발생합니다.
Stéphane Chazelas

4
@cuonglm 소스 코드를 확인했습니다. 그것은 궁극적으로 호출 get_current_user_info 하는 사용하는 getpwuid모든 플랫폼하지만 탠덤에 .
Michael Homer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.