正しいソリューション

正しいソリューション

私は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'

関連情報