為什麼我在嘗試循環使用者輸入的次數時會得到意外的輸出?

為什麼我在嘗試循環使用者輸入的次數時會得到意外的輸出?

我正在寫這個 bash shell 腳本:

#!/bin/bash

declare -i N
read N
for i in {1..$N}
do
  echo "Number: $i"
done

(我相信declare -i NN整數)

但是,在運行此命令時,我得到以下輸出:

>vim new.sh
>chmod +x passgen.sh
>./passgen.sh
15
Number: {1..15}

這裡我想從用戶那裡獲取限制,然後運行循環。

答案1

man bash

展開的順序是:大括號展開;波形符擴展、參數和變數擴展、算術擴展和命令替換(以從左到右的方式完成);分詞;和路徑名擴展。

正如您所看到的,大括號擴展是第一個,所以顯然它在您的問題中被跳過。我會使用不同的循環。

答案2

雖然已經指出了大括號擴展的問題,但我只想評論一下:

(我相信聲明 -i N 使 N 成為整數)

我會回答,是的,確實如此,這是一個問題,因為它使其成為命令注入漏洞。透過設定該整數屬性,每當為變數分配一個值時,該值都會被解釋為算術表達式。

如果使用者a[$(reboot)]在該read提示下輸入,則會導致嘗試重新啟動。

bash這是,zshksh計算算術表達式時的一個普遍問題。即使使用for (( i = 1; i <= N; i++ ))ksh93 樣式的形式(有或沒有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 ]]or也有問題。(( i < N ))bashzshksh

或者您可以使用awk/perl或任何適當的程式語言來執行循環,或者您可以先清理輸入。

相關內容