Bash
為什麼在嘗試循環使用者 輸入的次數時會得到意外的輸出?
我正在編寫這個 bash shell 腳本:
#!/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}
在這裡,我想從使用者那裡獲取限制,然後執行循環。
來自
man bash
:展開順序為:大括號展開;波浪號擴展、參數和變數擴展、算術擴展和命令替換(以從左到右的方式完成);分詞;和路徑名擴展。
正如您所看到的,大括號擴展是第一個,所以顯然它在您的問題中被跳過了。我會改用不同的循環。
雖然已經指出了大括號擴展的問題,但我將僅評論:
(我相信 declare -i N 使 N 成為整數)
我會回答,是的,確實如此,這是一個問題,因為它使其成為命令注入漏洞。使用該整數屬性集,無論何時為變數分配一個值,該值都會被解釋為算術表達式。
如果使用者
a[$(reboot)]
在該read
提示下輸入,例如,這將導致重新啟動嘗試。這是,的一個普遍問題
bash
,每當計算算術表達式時。即使使用ksh93 樣式的形式(帶或不帶)也會成為問題,因為 的內容仍然在該算術上下文中進行評估。zsh``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
’s[
仍將操作數-lt
視為算術表達式,因此仍會引入命令注入漏洞。不要用[[ $i -lt $N ]]
or(( i < N ))
inbash
//裡面也有問題zsh
。ksh
或者您可以使用
awk
/perl
或任何適當的程式語言來執行循環,或者您可以首先清理輸入。