チルダ(〜)が二重引用符内で展開しないのはなぜですか?


54

この答えと私自身の理解によると、チルダはホームディレクトリに展開されます。

$ echo ~
/home/braiam

さて、シェル拡張を機能させたいとき、つまり、などの変数名を使用し$FOO、予期しない文字、スペースなどを壊さないようにするには、二重引用符を使用する必要があります"

$ FOO="some string with spaces"
$ BAR="echo $FOO"
$ echo $BAR
echo some string with spaces

この展開がチルダで機能しないのはなぜですか?

$ echo ~/some/path
/home/braiam/some/path
$ echo "~/some/path"
~/some/path


3
また、コマンドラインでプログラム引数を提供する場合、コマンド引数で--path ~/myfileは展開されますが、展開されない場合、これに矛盾があることに注意してください--path=~/myfile
アンヘル14



このテーマのバリエーションは、unix.stackexchange.com / questions / 279565です。
JdeBP

回答:


45

理由は、二重引用符の中では、チルダ~には特別な意味がないため、リテラルとして扱われます。

POSIXは二重引用符を次のように定義しています

文字を二重引用符( "")で囲むと、文字のドル記号、バッククォート、およびバックスラッシュを除き、二重引用符内のすべての文字のリテラル値が保持されます。

...

アプリケーションは、二重引用符に二重引用符が含まれるように、バックスラッシュを前に付ける必要があります。パラメーター '@'は二重引用符内で特別な意味を持ちます

除く外$`\および@その他の文字はリテラル内の二重引用符として扱われ、。


9
その場合、私はあなたが使うべきだと思います$HOME
セス14

11
または~、たとえば、引用できませんls -l ~/"My Documents"
アンドリューメディコ14

これは非常に直感的ではありません。彼らがこれを行うことを選んだ理由は何ですか?(この答えは、実際には理由を示すものではなく、単に標準を指し示していますが、おそらく標準は理由のためにそのように書かれていると思われます。)
iconoclast

1
@iconoclastは、「なぜこのように実装されたのか」を本当に知りたい場合は、代わりにステファンの回答を読んでください。
ブライアン

2
だから、@iconoclast、なぜあるスカイブルーは?:) :) :)
ジェシーチザム

32

チルダ展開は、POSIXで次のように定義されています。

「チルダプレフィックス」は、単語の先頭に引用符で囲まれていない <tilde>文字と、単語内の最初の引用符で囲まれていない<slash>に先行するすべての文字、または<がない場合は単語内のすべての文字スラッシュ>。割り当てでは、複数のチルダ接頭辞を使用できます。[...]割り当ての<equals-sign>の後、引用符で囲まれていない<colon>のいずれか、または両方。[...]チルダプレフィックス内の文字が引用符で囲まれていない場合、<tilde>に続くチルダプレフィックス内の文字は、ユーザーデータベースからの可能なログイン名として扱われます。[...]ログイン名がnullの場合(つまり、チルダプレフィックスにチルダのみが含まれる場合)、チルダプレフィックスは変数HOMEの値に置き換えられます。HOMEが設定されていない場合、結果は指定されません。[...]

したがって、最短の答えは「そのように定義されているため」です。プレフィックスを含む文字を引用符で囲むと、~展開が抑制されます。

また、常に単一の単語になるように展開を定義するため、引用符は不要です。

チルダ展開の結果のパス名は、フィールド分割とパス名展開によって変更されないように、引用符で囲まれたものとして扱われます。

パスの一部が引用符を必要とし、残りがチルダ接頭辞である場合、チルダ展開と通常の引用符を簡単に組み合わせることができます。

$ cat ~/"file name with spaces"

より広い「理由」:単語分割の考えられる使用がないので~、それは引用されることを要求するのではなく、デフォルトの振る舞いであるべきです。引用符で囲む必要がないため、引用符~内に特別な意味を与えることは不必要な複雑さです。そしてもちろん、歴史的な理由から、たとえそれが望ましいとしても、今では変更できないということです。


このbashガイドによると、チルダの展開は空白の分離の前に行われます。ホームディレクトリに空白が含まれている場合でも、チルダ展開を安全に行う方法はありますか?通常、もちろん、このようなことはで行い""ます。
ルクレティエル

展開は1つの単語です。回答の2番目の引用箇所を参照してください。
マイケルホーマー

23

~ Kornシェルに追加され、後でPOSIXシェル仕様に追加されるずっと前に、Cシェルで作成されました。

Cシェルで~は、グロビング演算子(*.txtたとえば、拡張するルーチンと同じルーチンで拡張される)であったため、他のグロビングは二重引用符内で実行されませんでした。


11

これがなぜそのように設計されているのかは解りませんが、$HOME代わりに使用する必要がある場合は、代わりに使用~します。

$ echo "$HOME/some/path"
/home/braiam/some/path

6
これは動作しません~otheruser
ヨハネス・クーン14

2
確かにできますが、THEM =〜otheruserを使用して「$ THEM / some / path」を使用します。14
融合し

1
回避策は、二重引用符で囲まれた変数やその他のものとは異なる~otheruser扱い~方をするのがいかに悪い考えであったかを示しています。
iconoclast
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.