引用符で囲まれたチルダ( '〜')にcdできないのはなぜですか?


32

最初のスクリプトを書いて、これが基本的な質問であると確信していますが、誰かが私にできる理由を説明してください:

cd ~
cd bin
cd ~/bin
cd 'bin'

だがしかし

cd '~'
cd '~/bin'

私はする必要がありcd、私は(それはWindowsのだ引用符を必要とするので、ディレクトリ名のいずれかにスペースを持つディレクトリパスにProgram Filesワインの下)。2つのcdコマンドで回避できますが、なぜ~引用符で囲まないのですか?

入力cd '~'(またはcd "~")すると、次のようになります:

bash: cd: ~: No such file or directory

29
これを自問してみてください。もしそれがうまくいかなかった場合、どのようなcd名前のディレクトリに移動し~ますか?
ヨルグWミッターグ

2
補足として、スクリプトを作成する場合は、絶対パスを使用し、一緒に使用することは避けてcdください。変数を使用して、複数回入力したくないパス名を保存します。たとえば、pf=~/.wine/drive_c/Program\ Files/; cp /path/to/file "$pf"
デザート

8
@jamesqf:賢明なシステムは、なぜファイルやディレクトリに名前を付けたいかを私よりもよく知っていると推測するのでしょうか?また、Unixがパスコンポーネントセパレーターとパスターミネーターのマジックインバンドシグナリングを使用した理由を理解できませんでした。/またはという名前のファイル/ディレクトリの何が問題になっていますかNUL
ヨルグWミットタグ

3
@JörgWMittagおそらくcd ./~
-k_g

2
@jamesqf歴史的に、Unixファイルシステムでは、ファイル名に '/'(パス区切り文字)と '\ 0'(NUL-文字列終了文字)を除くすべての文字が許可されていました。他の制限はありません。多くのUnixファイルシステムの実装があるため、それらのいずれかに制限を導入すると、互換性が失われ、複雑さが増します。また、 '〜'拡張は比較的最近cshで導入され、bashでより広く導入されました。 '〜'文字が含まれるファイル/ディレクトリは不明ではありません(myfileのバックアップとしてのmyfile〜など)。
スーザンW

回答:


78

@karelが答えで指摘したように~、特殊文字であり、Bashによって現在のユーザーのホームディレクトリに展開されます。「Tilde Expansion」に関するBashのマニュアルを参照するか、マニュアルページ(man bash)で見出しの「Tilde Expansion」を検索してください。

周囲のあらゆる種類の引用符は、~このチルダの展開を防ぎます。


cd名前にスペースが含まれるディレクトリにそれをどのように使用できるかについての質問に答えるには、いくつかの選択肢があります:

  • 代わりに引用符を省略し、スペースをバックスラッシュでエスケープします。

    cd ~/foo/spaces\ are\ cool/bar
  • パスの残りを引用しますが、チルダと最初のスラッシュの周りは省略します。

    cd ~/"foo/spaces are cool/bar"

    ご覧のとおり、Bashで引用符で囲まれた文字列と引用符で囲まれていない文字列を、間にスペースを入れずに隣り合わせに記述するだけで連結できます。

  • $HOMEチルダの代わりに環境変数を使用します。チルダは「二重引用符」内で展開されます(「単一引用符」ではありません)。

    cd "$HOME/foo/spaces are cool/bar"

3
@rexkogitans ~'/...'は機能せず、この回答にはありません。~/'...'または~/"..."動作します。
hvd

tld; dr:thats shell shell
Sergiy Kolodyazhnyy

@hvdありがとう。タイプミスを修正。これは最も完全な答えであり、OPが何をしたいのかを解決する方法も説明しています。~/'path'行く方法です。
rexkogitans

1
@hvd好奇心のほんの少し、なぜ機能しません~'/...'か?スラッシュは特殊文字ではないため、引用符の内側でも外側でも機能するようです。
コドスジョンソン

6
@KodosJohnson「Tilde Expansion」に関するBashのマンページのセクションをご覧ください。その関連する段落は、以下のデザートの回答でも引用されています。TL; DR:単語の最初の文字が引用符で囲まれていないチルダである場合、チルダ展開が行われ、そのチルダと引用符で囲まれていない次のスラッシュの間のすべてが「チルダプレフィックス」と見なされます。このプレフィックスが+、-、数字、ユーザー名などの有効なものでない場合(引用符も使用できません)、展開は失敗し、リテラルの〜文字が表示されます。
バイトコマンダー

17

〜は、シェルによってログインしているユーザーのホームディレクトリとして解釈される特殊文字です。「〜」は、文字列を2つの一重引用符文字で囲むと、その文字列がリテラルテキスト文字列として解釈されるため、ログインしたユーザーのホームディレクトリとしてではなく、リテラル〜文字として解釈されます。


~意味でのエイリアスではありませんbashエイリアスは、単純なコマンドの最初の単語として使用される場合、文字列を単語に置き換えることができます。。以下の回答で説明するように、それはむしろ拡張です。
デザート

15

これはTilde Expansionbashと呼ばれる機能です。引用man bash

単語が引用符で囲まれていないチルダ文字で始まる場合( `〜 ')で最初の引用符で囲まれていないスラッシュ(または引用符で囲まれていないスラッシュがない場合はすべての文字)に先行するすべての文字は、チルダプレフィックスと見なされます。チルダプレフィックス内の文字が引用符で囲まれていない場合、チルダに続くチルダプレフィックス内の文字は、可能なログイン名として扱われます。このログイン名がヌル文字列の場合、チルダはシェルパラメータHOMEの値に置き換えられます。HOMEが設定されていない場合、代わりにシェルを実行しているユーザーのホームディレクトリが代わりに使用されます。

展開を機能させるには、チルダ文字~を引用符で囲む必要があります。そうしないと、文字は文字どおりに取得され、現在のディレクトリにディレクトリが存在しcdない場合は失敗します~。の引用の説明については、この集中的な回答を参照してくださいbash。したがって、パスの一部を引用する必要がある場合、次のことができます。

  1. 少なくとも単一引用符で引用する必要がある文字を引用します。例えば

    ~/dir' 'with' 'spaces/

    または

    ~/'dir with spaces/'
  2. 少なくとも二重引用符で引用する必要がある文字を引用します。例えば

    ~/dir" "with" "spaces/

    または

    ~/"dir with spaces/"
  3. バックスラッシュで引用する必要がある文字のみを引用します。例えば

    ~/dir\ with\ spaces/

Tilde Expansionには、さらに興味深い機能がいくつかあります。例えば:

  • ~+の値PWD、つまり現在の作業ディレクトリに展開します
  • ~-の値OLDPWD、つまり前の作業ディレクトリに展開します
  • ~john ログイン名「john」に関連付けられたホームディレクトリに展開します

ちなみに、バックスラッシュで「オーバークォート」することもできます。例えば、$ touch a; cd \a。(これはで問題が発生する可能性があると思いましたがcd \n、少なくとも私のバージョンの実験では問題なく動作することをbash示唆しています。)
LSpice

1

echoコマンドを使用して探索する

bashでの動作を調べる最も簡単な方法は、echoコマンドを使用することです。これを~使用する場合:

$ echo ~
/home/rick
$ echo '~'
~
$ echo "~"
~
$ echo `~`
bash: /home/rick: Is a directory

ご覧のとおり、単一引用符または二重引用符を使用~すると、文字列として解釈され、変数として展開されません。バックティック( `)を使用すると、コマンドとして実行され、エラーメッセージが生成されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.