変数を使用すると、中かっこ拡張を含むmkdirが失敗するようです。

変数を使用すると、中かっこ拡張を含むmkdirが失敗するようです。

Ubuntu 14.04.5 LTS GNU bash、バージョン 4.3.11(1)-リリース(x86_64-pc-linux-gnu)

mkdir -vp test{1..3}/{a,b,c}

うまくいく

mkdir: created directory 'test1'
mkdir: created directory 'test1/a'
mkdir: created directory 'test1/b'
mkdir: created directory 'test1/c'
mkdir: created directory 'test2'
mkdir: created directory 'test2/a'
mkdir: created directory 'test2/b'
mkdir: created directory 'test2/c'
mkdir: created directory 'test3'
mkdir: created directory 'test3/a'
mkdir: created directory 'test3/b'
mkdir: created directory 'test3/c'


S=1;E=3; LANG=EN mkdir -pv test{$S..$E}/{a,b,c}

mkdir: created directory 'test{1..3}'
mkdir: created directory 'test{1..3}/a'
mkdir: created directory 'test{1..3}/b'
mkdir: created directory 'test{1..3}/c'

うまくいかないようです。

失敗は一重引用符と二重引用符です。

S=1;E=3; LANG=EN mkdir -pv 'test{$S..$E}/{a,b,c}'
mkdir: created directory 'test{$S..$E}'
mkdir: created directory 'test{$S..$E}/{a,b,c}'


 S=1;E=3; LANG=EN mkdir -pv 'test{'$S'..'$E'}/{a,b,c}'
 mkdir: created directory 'test{1..3}'
 mkdir: created directory 'test{1..3}/{a,b,c}'

 S=1;E=3; LANG=EN mkdir -pv "test{S1..S3}/{a,b,c}"
 mkdir: created directory 'test{S1..S3}'
 mkdir: created directory 'test{S1..S3}/{a,b,c}'

forループを使用すること、パラメータ数に制限がある、フォルダに問題がある、またはprintfまたは「類似の問題」セクションに示されている同様の設定を使用できることを知っています。

しかし、私はこの特定のワイルドカードケースがなぜ失敗したのか知りたいです。

この質問のコメントで可能な解決策を見つけました。

Bashスクリプト一重引用符パラメータとワイルドカード値

ユーザーGalaxyを引用すると You can use eval to expand the whole line before executing it, e.g. $out=(eval "grep ..."), however, this works only if your input is trusted. –

S=1;E=3; LANG=EN eval mkdir -pv "test{$S..$E}/{a,b,c}"

mkdir: created directory 'test1'
mkdir: created directory 'test1/a'
mkdir: created directory 'test1/b'
mkdir: created directory 'test1/c'
mkdir: created directory 'test2'
mkdir: created directory 'test2/a'
mkdir: created directory 'test2/b'
mkdir: created directory 'test2/c'
mkdir: created directory 'test3'
mkdir: created directory 'test3/a'
mkdir: created directory 'test3/b'
mkdir: created directory 'test3/c'

働く

答え1

はい、Bashでは、変数が拡張される前に中かっこが最初に実行されます。これは、所望の方法で動作しないことを意味する。

$ a=1; b=5; echo {$a..$b}
{1..5}

(与えられた場合は中かっこを最初に展開し、次に{$a..$b}与えられた変数を展開します{1..5}。)

しかし、次のようにすることができます(用途を見つけた場合)。

$ aa=123;ab=456; echo $a{a,b}
123 456

Useはeval追加の評価を強制するために機能しますが、通常は望ましくない$記号を含むファイル名のコマンド拡張やその他の点を評価するため、通常は良い考えではありません。

以下の数値範囲がある場合は、ループを使用できます。

S=1;E=3;
for (( i=$S; i <= $E; i++ )) ; do 
     echo $i
done

または:

while [ $S -le $E ] ; do 
    echo $S 
    S=$[ $S + 1] 
done 

またzsh、支柱の拡張が必要な​​作業を行いますか?

$ zsh -c 'a=1; b=5; echo {$a..$b}'
1 2 3 4 5

関連情報