これはおそらく以前に尋ねられたと思いますが、Googleでは見つかりませんでした。
与えられた
~ == $HOME
本当だ?
理解しておくべき重要なことは、_~
_拡張はシェル(一部のシェルの)の機能であり、使用される場所に関係なくホームディレクトリを意味するのではなく、魔法の特徴ではありません。
コマンドが実行される前にシェルコマンドラインで使用される場合、_$var
_が特定の条件下でその値に展開されるように、(コマンドラインの解釈に使用されるアプリケーションであるシェルによって)拡張されます。
この機能は、1970年代後半にCシェルで最初に登場しました(ボーンシェルにはありませんでした。また、その前身であるトンプソンシェルにもありませんでした)は、後にコーンシェルに追加されました(新しいシェルは、 80年代)。最終的にPOSIXによって標準化され、現在fish
などの非POSIXシェルを含むほとんどのシェルで使用できます。
シェルでこのように広く使用されているため、一部の非シェルアプリケーションでも、ホームディレクトリを意味するものとして認識されます。これは、構成ファイルまたはownコマンドライン(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
ではパターンとして採用されていますが、4.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はその動作を残すため、拡張機能として未定義)。
4.0より前のバージョンのksh88およびbash
では、チルド展開はリストコンテキストでグロビング(ファイル名生成)を受けていました。
_$ 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
_の展開方法を決定できます。任意のシステムの任意のバージョンのBashでは、はい 。独自の用語としての~
は、次のように展開するように定義されています。
$ HOMEの値
そのため、現在のシェルに対する$HOME
の内容と常に同じになります。 user
のホームディレクトリの~user
など、他のいくつかのチルダ拡張がありますが、引用符で囲まれていない単一の~
は、それ自体で常に"$HOME"
に拡張されます。
~
と$HOME
の動作が異なる場合があることに注意してください。特に、$HOME
スペース(または他の [〜#〜] ifs [〜#〜] 文字)が含まれている場合、$HOME
(引用符なし)は複数の単語に展開されますが、~
は常に一つの単語。 ~
は"$HOME"
(引用)と同等に展開されます。
あなたの特定の質問に関して:
[[ $HOME == ~ ]]
[[
suppresses ワード分割であるため、常にtrueです。 HOME
に パターンマッチング 文字が含まれている場合、[[ ~ == $HOME ]
は存在しない可能性がありますが、[[ ~ == "$HOME" ]]
(つまり、引用符で囲まれた"$HOME"
)は常にtrueです。単一のブラケット内で使用すると、スペースまたは特殊文字を含むHOME
の値の構文エラーになる可能性があります。賢明なホームディレクトリ構成の場合、~
と"$HOME"
は同じであり、等しいと比較されます。
StéphaneChazelasがコメントで~
と$HOME
が異なる値を与える場合を指摘しました: unset HOME
の場合、~
Bashを使用すると getpwuid
を呼び出して、パスワードデータベースから値を読み取ります。このケースは、$HOME
の構成を変更していないという条件によって除外されていますが、ここでは完全を期して説明します。