これが状況です(私はMac、OS X El Capitanを使用しています):
# This works:
$ cd /Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates/;
# These do not work:
$ INSTALL_DIR=/Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates;
$ cd $INSTALL_DIR
# Moves me here: /Applications/Adobe
$ cd "$INSTALL_DIR"
-bash: cd: /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates: No such file or directory
$ cd "${INSTALL_DIR}"
-bash: cd: /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates: No such file or directory
私の目標は、tar
で$INSTALL_DIR
を次のように使用することです。
$ tar -xz $SOURCE_Zip --strip-components 1 -C $INSTALL_DIR "*.ait";
残念ながら、-C
(宛先ディレクトリに変更)は$INSTALL_DIR
のスペースが好きではありません。引用符を使用すると、*
が機能しなくなります。
このシナリオを処理するエレガントな方法はありますか?
*が引用されていない場合、シェルはコマンドを実行する前に引数リストを展開します。それは展開引数リストをプログラムに渡します。
*が引用符付き文字列に含まれている場合、プログラムに渡される前にシェルによって展開されません。
パスを展開して別の変数に割り当て、次に引数として渡すときに2番目の変数を引用してみてください。
問題はtarではなく、シェルコードにあります。 -C
オプションの引数は、ワイルドカードパターンではなくパスであることが想定されています。 cd
コマンドでまったく同じ問題が発生したことに注意してください。
INSTALL_DIR
変数にワイルドカードパターンを格納しました。 -C $INSTALL_DIR
を記述する場合、これは「split + glob」演算子を適用します。変数の値を取り、空白で分割し、各Wordをワイルドカードパターンとして解釈してから、展開します。ここで、変数の値は/Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates
で、3つの単語に分割されます/Applications/Adobe
、Illustrator*/Cool
、Extras.localized/en_US/Templates
;中央のWordにはワイルドカード(*
)が含まれているため、ワイルドカードパターンとして解釈されますが、どのファイルにも一致しないため、パターンはそのまま残されます。これにより、-C
オプションの引数が文字列/Applications/Adobe
になり、tar
コマンドにはIllustrator*/Cool
とExtras.localized/en_US/Templates
の2つの引数があります。
二重引用符を使用する場合、"$INSTALL_DIR"
は変数INSTALL_DIR
の値になります。 *
がまだ展開されていないため、まだ展開されていません。
経験則として、ワイルドカードは、複数の単語が予想されるコンテキストで展開されます。結局のところ、一般に、ワイルドカードパターンは複数のファイルに一致します。結果は単一の文字列であることが期待されるため、割り当ての右側はワイルドカード展開を抑制します。代わりにリストを取得するには、文字列変数ではなく配列変数に割り当てます。
INSTALL_DIRS=(/Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates)
複数のバージョンのIllustratorがインストールされている場合、複数の配列要素が存在する可能性があります。最後の要素を見てみましょう。
INSTALL_DIR=${INSTALL_DIRS[$((${#INSTALL_DIRS}-1))]}
ここで、INSTALL_DIR
は既存のファイルへのパスです(ワイルドカードが一致したと想定)。通常どおり使用できます(つまり、二重引用符で囲むことができます)。
tar -xz "$SOURCE_Zip" --strip-components 1 -C "$INSTALL_DIR" "*.ait"