Bash
評估 for 循環時出錯
我正在編寫一個接受兩個參數的腳本:
#! /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
. (請參閱在大括號擴展之前執行參數擴展?)
那是因為shell評估了
;
,所以eval
沒看到。您必須轉義任何 shell 特殊字元以延遲其評估,並且 pass 字面意思是
eval
:eval for i in \{"$1".."$2"\}\; do echo \"\$i\"\; done
該行在第一個元字元處換行,即
;
(在本例中)。該行:
eval for i in {$1..$2}; do echo $i; done
分為這三個命令:
eval for i in {$1..$2}; do echo $i; done
嘗試在
do
沒有以前的for
,while
的情況下執行 a 是until
行不通的。它將引發錯誤情況:意外標記“do”附近的語法錯誤
發生這種情況是因為前
for
一個作為參數隱藏在 command 中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 and $ 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'