シェル変数のチルダ拡張はどのように機能しますか?

シェル変数のチルダ拡張はどのように機能しますか?

スクリプトのテスト中に興味深い事実を見つけました。

以下を実行すると、シェルで手動で自分のディレクトリを見つけることができます。

$ ls ~/db_backups/
test1  test2
$ 

ただし、チルダを使用してシェル変数にディレクトリの場所を割り当てても機能しません。私は一重引用符と二重引用符を使用してみました。

$ backupfolder='~/db_backups'
$ echo $backupfolder
~/db_backups
$ ls $backupfolder
ls: cannot access '~/db_backups': No such file or directory
$ 

シェル変数内でチルダの置き換えはどうなりますか?ディレクトリ名にチルダを手動で使用するのと同じように、変数でディレクトリが見つからないのはなぜですか?

答え1

チルダが変数拡張結果の一部である場合、シェルはbash拡張されません。~引用符なしのチルダプレフィックス(~または現在のユーザー名の場合~+)は、開始または直後にのみ現在のユーザーのホームディレクトリに展開されます。~usernameusername=:/

あなたの場合、変数に割り当てるときに拡張を実行する方が簡単ですbackupfolder。チルダを離すとこうなります。引用しない(一重引用符や二重引用符を使用しないでください):

backupfolder=~/db_backups
ls "$backupfolder"

...または$HOME代わりに使用する場合(単一引用符なし):

backupfolder=$HOME/db_backups
ls "$backupfolder"

両方の割り当てでは、シェルは割り当て演算子の右側の値をdb_backups現在のユーザーのホームディレクトリにある呼び出しパス名に拡張します。

通常、$HOMEスクリプト内で使用する方が簡単で、インタラクティブな~セッションに残すと便利なショートカットとして機能します。このHOME変数は常に次のように動作します。変える

答え2

~user/簡単に言えば、(または)は明示的で、引用符を使用しないで~/ください。変数拡張の結果にはなりません。

あなたはbackupfolder=~/'db_backups'成功する必要がありますls $backupfolder

長い説明

チルダ拡張が発生する唯一の方法は実際です引用しない ~多い場合引用しない /、または文字列の終わり。

Anはecho ~cris/'one space'チルダ(およびユーザー名)を拡張しますが、実際のチルダがない限り、~チルダは拡張されません。興味深いことに、これらのコマンドにはパス値にスペースが含まれているため、引用符が必要ですone space

また、これらのリストのいずれかが拡張されている場合(bashで中括弧を拡張した後に拡張されます):チルダ拡張、パラメータおよび変数拡張、算術拡張、およびコマンドの置換実行されると(左から右へ)、リスト内の他の単語は同じ単語に再適用されません(すべて同時に発生します)。

その後、中括弧拡張(最初の拡張)をリストを介してさらに拡張することができ、(最後の2つの拡張)単語分割とパス名拡張が前のステップの結果に適用されます。たとえば、次の3つの変数が展開されます。

$ echo $HIST{FILE,FILESIZE,SIZE}
/home/cris/.bash_history 2000 1000

ガセエ拡張の結果は、変数拡張によって再び拡張される。ただし、変数の拡張は他の拡張に再拡張されません。

$ b='$((2+2))'; echo $b
$((2+2))

~user/簡単に言えば、(または)は明示的で、引用符を使用しないで~/ください。変数拡張の結果にはなりません。

算術拡張は、「一度だけ拡張」ルールには該当しません。算術拡張では、拡張を複数のステップで繰り返すことができます。たとえば、

$ a=b; b=c; c=d; d=23; echo $(($a))
23

私はリストしていませんが、process substitutionこれも追加する必要があることに注意してください。

関連情報