〜常に$ HOMEと同じですか?

〜常に$ HOMEと同じですか?

この質問が以前にリクエストされた可能性がありますが、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の拡張は~モードと見なされていますが、ksh4.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引用符のため)。
  • 呼び出し時shexport "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、、(完了すると)は、ディレクトリスタック(~-以前の場所)でディレクトリを拡張するために使用されます。~-2cd
  • 動的に名前が付けられたディレクトリ。拡張方法を決定するための独自のメカニズムを定義できます~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ここでは完全性のために言及します。

関連情報