この質問が以前にリクエストされた可能性がありますが、Google で見つかりませんでした。
与えられた
- Linuxカーネル
- $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の拡張は~
モードと見なされていますが、ksh
4.0bash
以降はもうそうではありません。)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およびbash
4.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
ここでは完全性のために言及します。