複数のユーザー入力を繰り返そうとすると、予期しない出力が表示されるのはなぜですか? [コピー]

複数のユーザー入力を繰り返そうとすると、予期しない出力が表示されるのはなぜですか? [コピー]

私は次の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

支柱の拡張の問題が指摘されていますが、私は次のように言及したいと思います。

(私は-i NステートメントがNを整数にすると信じています)

私は答えます。はい。命令注入の脆弱性になるため問題になります。この整数プロパティを設定すると、変数に値が割り当てられるたびにその値が算術式として解釈されます。

ユーザーがa[$(reboot)]このreadプロンプトを入力すると、再起動が試みられます。

bashこれは算術式を評価するzshときによく見られる問題ですkshfor (( i = 1; i <= N; i++ ))ksh93スタイル形式(含めるかどうかにかかわらず)を使用しても、declare -i Nその内容はNまだその算術文脈で評価されるため、問題が発生する可能性があります。

for i in {1..$N}declare -i Nksh、zsh、またはyash -o braceexpand(横説説を繰り返すがコマンドインジェクションの脆弱性を引き起こさない)場合は問題ありません(なし)。またはsh実装shksh

#! /bin/sh -
IFS= read -r N
i=1; while [ "$i" -lt "$N" ]; do
  printf '%s\n' "Number: $n"
done

ksh[オペランドはまだ-lt算術式として扱われるため、命令注入の脆弱性が引き続き発生します。 // [[ $i -lt $N ]]orも使用しないでください。(( i < N ))bashzshksh

あるいは、ループを実行するために適切なプログラミング言語を使用するか、入力を最初にクリーンアップすることもできますawkperl

関連情報