私は2つのパラメータを受け入れるスクリプトを書いています。
#! /bin/bash
eval for i in {$1..$2}; do echo $i; done
私は次のように実行します:
$ ./myscript 0002 0010
syntax error near unexpected token `do'
このエラーはなぜ発生しますか?
ループをグループ化する必要があるからだと思います。ただし、eval for i in {$1..$2}; do echo $i; done
に置き換えると、eval { for i in {$1..$2}; do echo $i; done; }
エラーはまだ存在します。
注:中かっこ拡張の前に使用したいと思いますeval
。私の例では、希望の出力はです0002 0003 0004 0005 0006 0007 0008 0009 0010
。支柱を拡張する前にパラメータ拡張を実行しますか?)
答え1
その理由は、シェルがそれを評価する;
ためにeval
これを見ることができないからです。
評価を遅らせるには、シェル特殊文字をエスケープする必要があり、文字通り渡すと次のようになりますeval
。
eval for i in \{"$1".."$2"\}\; do echo \"\$i\"\; done
答え2
行は最初のメタ文字;
(この例では)から区切られています。
銀行:
eval for i in {$1..$2}; do echo $i; done
3つのコマンドに分けられます。
eval for i in {$1..$2};
do echo $i;
done
do
以前for
、、while
なしでaを実行しようとするとuntil
機能しません。エラー条件が発生します。
予期しないマーカー 'do'の近くに構文エラーがあります。
これは、前のエントリがコマンドfor
のパラメータとして隠されているために発生しますeval
。
考えられる解決策は、すべてを引用して拡張したい項目だけを省略することです。変数$1
と次が必要だと思います$2
。
eval 'for i in {'$1'..'$2'}; do echo $i; done'
それは動作します:
$ ./myscript 0002 0010
0002
0003
0004
0005
0006
0007
0008
0009
0010
ただし、このスクリプトはeval
外部入力を使用するため、非常に安全ではありません。
正しいソリューション
より安全なスクリプトは、次のように$ 1と$ 2を削除し、変数を正しく参照します。
#!/bin/bash
a=${1//[^0-9]/} ### select only numbers from first parameter.
b=${2//[^0-9]/} ### select only numbers from second parameter.
eval 'for i in {'"$a"'..'"$b"'}; do echo $i; done'