3

一連のディレクトリを調べてファイルの存在を確認し、見つかった場合は、を介してディレクトリスタックにプッシュするスクリプトを作成していますpushddirsコマンドはめちゃくちゃ不快で、その内容のbash変数形式に出くわしました。$DIRSTACK

$DIRSTACKスタック内のディレクトリの配列です。常に1つのエントリ、現在の作業ディレクトリ、およびプッシュされたディレクトリが続くことが保証されています。

ディレクトリのリストを反復処理しようとしていますが、自動的に生成しようとしているシーケンスの長さをforループで受け入れられないようです。

for i in {1..${#DIRSTACK[*]}}; do
  echo ${DIRSTACK[$i]}
done

実行すると、bashは次のエラーで失敗します。

line 72: {1..2}: syntax error: operand expected (error token is "{1..2}")

正直なところ、for i in {1..5}問題なくスクリプトを何度も手動で記述していて、エラーメッセージが表示されたため、配列アイテムの数の拡張が希望どおりに機能しているようです。

このエラーが発生するのはなぜですか?

4

2 に答える 2

5

中にパラメータがある場合、ブレース拡張は正しく機能しません。これはDIRSTACK、この場合、ブレースが展開されるまでパラメータが展開されないためです

bashのmanページから:

ブレース展開は他の展開の前に実行され、他の展開に固有の文字は結果に保持されます。厳密にテキストです。Bashは、展開のコンテキストまたは中括弧の間のテキストに構文上の解釈を適用しません。

単に配列をループしたい場合は、以下を使用してみませんか?

for i in "${DIRSTACK[@]}"
do
    echo $i
done

または、配列の長さを明示的に使用する場合は、次のようにします。

for (( i = 0 ; i < ${#DIRSTACK[@]} ; i++ ))
do
    echo ${DIRSTACK[$i]}
done
于 2012-06-20T07:51:51.473 に答える
2

シーケンス式に似た構造は、seq(1)コマンドを使用することです。

特定のケースでは、次を使用できます。

for i in $(seq ${#DIRSTACK[*]}); do
  echo ${DIRSTACK[$i]}
done

ただし、@dogbaneの回答に対するコメントを考えると、配列内の要素の数を繰り返し処理しているが、末尾を過ぎてインデックスを作成しているため、これはまだ希望どおりには機能しません。

必要なことは、配列でも機能するbash の部分文字列展開を使用することで簡単に実現できます。

for dir in "${DIRSTACK[@]:1}" ; do
  echo $dir
done
于 2012-06-20T09:09:16.243 に答える