~ 항상 $HOME과 같나요?

~ 항상 $HOME과 같나요?

이 질문이 이전에 요청되었을 수도 있지만 Google을 통해 찾을 수 없다는 것을 알고 있습니다.

주어진

  • 리눅스 커널
  • $HOME 구성이 변경되지 않았습니다.
  • 세게 때리다

~ == $HOME그것이 사실일까요 ?

답변1

이해해야 할 중요한 점은 ~확장은 쉘(일부 쉘)의 기능이며 마법의 문자는 아니지만 사용되는 모든 홈 디렉토리를 참조한다는 것입니다.

$var명령을 실행하기 전에 셸 명령줄에서 사용될 때 특정 조건에서 해당 값으로 확장되는 것과 마찬가지로 명령줄을 해석하는 데 사용되는 응용 프로그램인 셸에 의해 확장됩니다 .

이 기능은 1970년대 후반 C-쉘에 처음 등장했으며(Bourne 쉘에는 이 기능이 없었고 이전 쉘인 Thompson 쉘에도 없었습니다) 나중에 Korn 쉘(Bourne 쉘에 구축된 최신 쉘)에 추가되었습니다. . 80년대). 이는 결국 POSIX에 의해 표준화되었으며 현재는 POSIX가 아닌 셸(예: fish.

쉘에서 광범위하게 사용되기 때문에 일부 비쉘 응용프로그램에서도 이를 홈 디렉토리로 인식합니다. 이는 많은 애플리케이션 프로필이나 애플리케이션의 경우입니다.내 자신의명령줄( mutt, slrn, vim...).

bash특히 (많은 Linux 기반 운영 체제에서 널리 사용되는 GNU 프로젝트의 셸입니다 sh. )POSIX 규칙확장 및 POSIX에서 지정하지 않은 영역 과 관련하여 ~동작은 Korn 셸과 대부분 유사합니다(Korn 셸의 부분 복제임).

확장은 대부분의 위치에서 발생 하지만 $var(작은따옴표 내 제외), ~사실 이후의 확장은 몇 가지 특정 조건에서만 발생합니다.

문자열이 필요한 컨텍스트에서 자체 매개변수를 사용하여 목록 컨텍스트에서 사용될 때 확장됩니다.

확장할 수 있는 몇 가지 예는 다음과 같습니다 bash.

  • cmd arg ~ other arg
  • var=~
  • var=x:~:x(POSIX 요구 사항, PATH, MANPATH...과 같은 변수에 대한)
  • for i in ~
  • [[ ~ = text ]]
  • [[ text = ~ ]](AT&T의 확장은 ~모드로 간주되었지만 ksh4.0 bash부터는 더 이상 그렇지 않습니다.)
  • case ~ in ~) ...
  • ${var#~}(다른 껍질에는 없지만)
  • cmd foo=~(단, 로 호출할 때는 아니고 sh, 왼쪽이 =따옴표가 없는 변수 이름 모양인 경우에만 해당 bash)
  • cmd ~/x(분명히 POSIX에서 요구됨)
  • cmd ~:x(그러나 그렇지 x:~:x않거나 x-~-x)
  • a[~]=foo; echo "${a[~]} $((a[~]))"(다른 쉘에는 없음)

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

  • echo "~" '~'
  • echo ~@ ~~(또한 이는 ~u사용자의 홈 디렉토리로 확장한다는 의미입니다 u.)
  • echo @~
  • (( HOME == ~ )),$(( var + ~ ))
  • :( 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 이전 버전에서는 목록 컨텍스트(파일 이름 생성)에서 물결표 확장이 와일드카드로 사용되었습니다.

$ 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.

답변2

모든 시스템의 모든 Bash 버전에서 그렇습니다.. ~용어 자체는 다음과 같이 확장된 것으로 정의됩니다.

$HOME의 가치

$HOME따라서 현재 쉘의 내용과 항상 동일합니다 . ~user에 대한 홈 디렉토리 와 같은 여러 다른 물결표 확장이 있지만 user따옴표가 없는 단일 ~물결표 확장은 항상 로 확장됩니다 "$HOME".

참고하시기 바랍니다,행동~$HOME일부 경우에는 다를 수 있습니다. 특히 $HOME공백(또는 기타IFS문자), $HOME따옴표 없이는 여러 단어로 확장되지만 ~항상 단일 단어입니다. (참조) 확장 ~과 동일합니다 ."$HOME"

귀하의 특정 질문과 관련하여:

[[ $HOME == ~ ]]

항상 옳으니까[[ 막다분사. 아마 있으면 [[ ~ == $HOME ]없을 것 같아요HOME패턴 매칭그 안의 문자 but [[ ~ == "$HOME" ]](즉, 참조 "$HOME")은 항상 참입니다. HOME단일 괄호 안에 사용하면 공백이나 특수 문자가 포함된 값 에 대해 구문 오류가 발생할 수 있습니다. 합리적인 홈 디렉토리 구성의 경우 ~"$HOME"는 동일하며 동일합니다.


Stéphane Chazelas는 주석에서 ~$HOME다른 값을 제공하는 사례를 지적했습니다.unset HOME, Bash를 사용하면 ~호출됩니다.getpwuid비밀번호 데이터베이스에서 값을 읽습니다. 이 경우는 구성을 변경하지 않으면 제외되지만 $HOME여기서는 완전성을 위해 언급하겠습니다.

관련 정보