web-dev-qa-db-ja.com

Linux環境変数のスペース?

指定されたディレクトリ:/media/foo/can haz/bar、編集してみましたbash.rc with:

export Foo=/media/foo/can haz/bar
export Foo=/media/foo/can\ haz/bar
export Foo='/media/foo/can haz/bar'
export Foo="/media/foo/can haz/bar"
export Foo='"/media/foo/can haz/bar"'
export Foo="'/media/foo/can haz/bar'"

しかし、毎回、次のようなものを機能させることができませんでした("$Foo"):

cd $Foo

Linuxシステムでスペースを使用して環境変数を設定するにはどうすればよいですか?

4
A T

問題は、環境変数にスペースが含まれていることではありません。あなたは忘れています あなたの議論を引用してください

cd "$Foo"

$Fooを引用符で囲まない場合、 デフォルトでは空白で引数が区切られる であるため、cdコマンドには実際には2つ(またはそれ以上)の引数が表示されます。特定のケースでは、シェルがスペースでそれらを分割するため、/media/foo/canhaz/barを別々に渡します。変数を二重に引用することは、開発するのに良い習慣であり、空白が含まれる多くの場合にあなたを救うでしょう。

引用符なしでこれを実現するための本当に醜い方法が必要な場合は、cdビルトインを次のように上書きします。

cd() { builtin cd "$*"; }

パスにスペースが含まれている場合、これは機能します。これは、$*に最初のIFS文字(通常はスペース)で区切られた個々の引数(/media/foo/canおよびhaz/bar)が含まれるためです。二重引用符でそれらを接着します。

ただし、このような組み込みを上書きすることは決して良い考えではありません。

8
slhck

@slhckが言ったように、これを行う正しい方法は、変数参照を二重引用符で囲むことです(例:cd "$Foo")。この理由は、シェルがコマンドラインのさまざまな側面を解析する順序です。最初に引用符とエスケープをスキャンし(そして効果を適用するときにそれらを削除し)、次に変数参照をそれらの値に置き換えます(例:$Foo-> /media/foo/can haz/bar)次に、置き換えられた値に戻り、ワイルドカード展開を適用します(*.txt-> a.txt b.txtなど)および単語分割(/media/foo/can haz/bar-> "/ media/foo/can" "haz/bar")が、戻ることはなく、変数値で引用符やエスケープを探します。その結果、変数の値に引用符やエスケープを埋め込むと、少しでも役立つものはありません;それらがコマンドラインの一部になるまでに、意図した効果を得るには遅すぎます。展開された値でWordが分割されないようにする3つの方法しか知りません。

  1. 変数参照を二重引用符で囲みます。これはそれほど便利ではありませんが、標準のシェル構文の要件です。
  2. IFS(展開された変数での単語分割に使用される文字のリスト)の値を変更します。次に、標準のWord分割動作に依存するすべてのスクリプトが奇妙に壊れることに注意してください。これをしないでください。真剣に。
  3. 拡張変数でWord分割を行わないシェルに切り替えます:zsh。 bashとのその他の違いに慣れる必要がありますが、本当にこれが必要な場合は、これが最善の方法です。自分では使っていませんが、好きな人は….
2
Gordon Davisson