次の2行のコードがbashスクリプトで実行されると、「ls」はファイルが存在しないことを報告します。
dirs=/content/{dev01,dev02}
ls -l $dirs
-xオプションを指定してスクリプトを実行すると、変数が一重引用符で囲まれているように見えます(グロブを防止します)。
+ dirs=/content/{dev01,dev01}
+ ls -l '/content/{dev01,dev01}'
ls: /content/{dev01,dev01}: No such file or directory
対話型シェル(引用符を除く)から「ls」コマンドを実行すると、2つのディレクトリが返されます。
私はBashリファレンスマニュアル(v 3.2)を読んでいて、ファイル名の展開が行われない理由(-fをシェルに渡していない)、またはそれを確実にするために設定できるものを確認できませんグロビングが発生します。
私はそれが展開の順序だと思います:
展開の順序は次のとおりです:
brace expansion
、チルダ展開、パラメーター、variable
および算術展開とコマンド置換(左から右に実行)、ワード分割、およびpathname expansion
。
したがって、変数が置換されると、中括弧の展開は行われなくなります。これは私にとってはうまくいきます:
eval ls $dirs
Evalには十分注意してください。それはそのままのものを実行します。したがって、dirsにf{m,k}t*; some_command
が含まれている場合、lsが終了した後でsome_commandが実行されます。現在のシェルでeval
に指定した文字列を実行します。存在するかどうかに関係なく、/content/dev01 /content/dev02
をlsに渡します。ものの後に*
を置くと、パス名が展開され、存在しないパスが省略されます。
dirs=/content/{dev01,dev02}*
私はこれについて100%確信はありませんが、私には理にかなっています。
ここ は、あなたが何をしようとしているのかについての優れた議論です。
簡単に言えば、配列が必要だということです。
dirs=(/content/{dev01,dev01})
しかし、結果をどうするかは、あなたが目指していたものよりも複雑になる可能性があると思います。
これはファイル名の展開ではなく、中括弧の展開です。違いはわずかですが、存在します。ファイル名の展開では、結果として既存のファイルのみを受け取りますが、ブレース展開では、あらゆる種類の文字列を生成できます。
http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion
http://www.gnu.org/software/bash/manual/bashref.html#Filename-Expansion
今、これは私のために働いたものです:
#!/bin/sh
dirs=`echo ./{dev01,dev02}`
ls $dirs
(私のような)Googleでこれを見つけた人にとって、@ Peterと@feohの答えは、「bashスクリプトで変数をグロブ化する方法」の一般的な解決策です。
list_of_results=(pattern)
pattern
に一致する既存のファイル名を配列list_of_results
に保存します。 list_of_results
の各要素は、1つのファイル名、スペース、およびすべてを保持します。
各結果には、0から始まる"${list_of_results[<index>]}"
の<index>
としてアクセスできます。リスト全体を"${list_of_results[@]}"
として正しく引用符で囲んで取得できます。
私はあなたが必要とするものは配列であると思いますが、それはあなたを新しいバッシに制限するでしょう。 evalを使用するよりも節約されます。
dirs=( /"content with spaces"/{dev01,dev02} )
dirs=( /content/{dev01,dev02} )
ls -l "${dirs[@]}"
/content/{dev01,dev02}
次のように展開されます:
"/content/dev01" "/content/dev02"
これらのディレクトリの存在は、拡張とは無関係です。
ブレース展開に変数を割り当てると、予測できなくなります。
dirs=/content/{dev01,dev02}
に変わるかもしれません
"/content/dev01"
または
"/content/dev01 /content/dev02"
または
"/content/dev01" "/content/dev02"
または
"/content/{dev01,dev02}"
中括弧を何らかの方法で引用すると、展開されないため、結果には中括弧が含まれ、ほとんど意味がなくなります。
ファイルをグロブしたいので、中括弧展開を使用すべきではありません。この場合のブレース展開の使用はアンチパターンであり、ジョブには間違いなく間違ったツールです。
あなたが望むのは extended globbing :
shopt -s extglob # likely already set in interactive shells
dirs=/content/@(dev01|dev02)
ls $dirs
ls `echo $dirs`
cygwinで動作します。
誰も対処していない問題は、変数の割り当てが違いを生むことです。
dirs=/content/{dev01,dev02}
とは異なる展開
echo /content/{dev01,dev02}
問題は、展開の結果をdirs
に割り当てる方法です。