私は次の bash シェル スクリプトを書いています:
#!/bin/bash
declare -i N
read N
for i in {1..$N}
do
echo "Number: $i"
done
(整数にdeclare -i N
なると思います)N
ただし、これを実行すると、次の出力が得られます。
>vim new.sh
>chmod +x passgen.sh
>./passgen.sh
15
Number: {1..15}
ここでは、ユーザーから制限を取得して、ループを実行します。
答え1
からman bash
:
展開の順序は、中括弧展開、チルダ展開、パラメータと変数の展開、算術展開、コマンド置換(左から右に実行)、単語分割、パス名展開です。
ご覧のとおり、中括弧の展開が最初なので、どうやら問題ではスキップされているようです。代わりに別のループを使用します。
答え2
ブレース拡張の問題はすでに指摘されていますが、私は次の点についてコメントします。
(declare -i N は N を整数にすると思います)
答えは「はい、そうです」です。これはコマンド インジェクションの脆弱性となるため問題です。整数属性が設定されている場合、変数に値が割り当てられるたびに、その値は算術式として解釈されます。
たとえば、ユーザーがa[$(reboot)]
そのプロンプトで入力すると、再起動が試行されます。read
bash
これは、算術式が評価されるたびにzsh
、および で発生する一般的な問題です。の有無にかかわらず、ksh93 スタイルの形式を使用した場合でも、 の内容がその算術コンテキストで評価されるため、問題になります。ksh
for (( i = 1; i <= N; i++ ))
declare -i N
N
for i in {1..$N}
declare -i N
ksh、zsh、またはでは ( なし)で問題ありませんyash -o braceexpand
(意味不明なループが発生しますが、コマンド インジェクションの脆弱性は発生しません)。また、実装が に基づいていないsh
場合は、標準の構文を使用することもできます。sh
ksh
#! /bin/sh -
IFS= read -r N
i=1; while [ "$i" -lt "$N" ]; do
printf '%s\n' "Number: $n"
done
ksh
は[
依然として のオペランドを-lt
算術式として扱うため、コマンド インジェクションの脆弱性が依然として生じます。/ /内で[[ $i -lt $N ]]
または を使用しないでください。これも問題を引き起こします。(( i < N ))
bash
zsh
ksh
あるいは、awk
/perl
または適切なプログラミング言語を使用してループを実行することも、最初に入力をサニタイズすることもできます。