6

回避方法がわからない奇妙な動作を見つけました。

$ var1=*

$ echo $var1
Audiobooks Downloads Desktop (etc.)

$ ls $var1
Audiobooks:

Downloads:
(etc)

すべて問題ないようです。宣言時に、変数が展開され、他のすべてが機能します。しかし、これを見てください:

$ var2=~/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm

$ echo $var2
/home/yajo/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm

$ ls $var2
ls: no se puede acceder a /home/yajo/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm: No existe el fichero o el directorio

$ ls /home/yajo/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm
/home/yajo/rpmbuild/RPMS/noarch/enki-12.10.3-1.fc18.noarch.rpm  /home/yajo/rpmbuild/SRPMS/enki-12.10.3-1.fc18.src.rpm
/home/yajo/rpmbuild/RPMS/noarch/enki-12.10.3-1.fc19.noarch.rpm  /home/yajo/rpmbuild/SRPMS/enki-12.10.3-1.fc19.src.rpm

今回は、 at 宣言のみ~が展開されるため、 に引数として渡すことができませんls。ただし、同じ文字列をそのまま渡すと、期待どおりの結果が得られます。

質問は次のとおりです。

  • 拡大するときとしないときがあるのはなぜですか?
  • $var1withの動作を模倣する方法は$var2?

ありがとう。

特記事項:

二重引用符と単一引用符で同じことを試みましたが、同じ悪い結果になりました。

4

1 に答える 1

11

シェルがコマンド ラインのさまざまな側面を解析する順序は明らかではなく、このような場合に重要です。

まず、ワイルドカードは宣言時に展開されず、変数値が置換された後に展開されます (注: これらの例では、ファイルシステムがあるふりをします):

$ var1=*
$ echo "$var1"   # double-quotes prevent additional parsing of the variable's value
*
$ echo $var1     # without double-quotes, variable value undergoes wildcard expansion and word splitting
Audiobooks:

Downloads:
(etc)

ところで、宣言~ 展開され、さらに混乱します。

$ var2=~
$ echo "$var2"   # again, double-quotes let me see what's actually in the variable
/home/yajo

問題~/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm1は、シェルが置換後の値に対してワイルドカード展開 ( *) を実行する一方で、中括弧展開 ( ) を実行しない{SRPMS,RPMS/*}ため、実際には名前に中括弧とコンマが含まれるディレクトリ名を探していることです...そして何も見つかりません.

これを処理する最善の方法は、通常、ファイル リストを配列として格納することです。これを正しく行うと、宣言時にすべてが展開されます。

$ var2=(~/rpmbuild/{SRPMS,RPMS/*}/enki-*.rpm)
$ echo "${var2[@]}"   # This is the proper way to expand an array into a word list
/home/yajo/rpmbuild/RPMS/noarch/enki-12.10.3-1.fc18.noarch.rpm  etc...

配列は bash の拡張機能であり、プレーンな POSIX シェルでは機能しないことに注意してください。そのため、スクリプトは必ず#!/bin/bashではなくで始めてください#!/bin/sh

于 2013-07-07T15:00:32.730 に答える