正确的解决方案

正确的解决方案

我正在编写一个接受两个参数的脚本:

#! /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; doneeval { for i in {$1..$2}; do echo $i; done; },错误仍然存​​在。

注意:我希望在大括号扩展之前使用eval.我的示例所需的输出是0002 0003 0004 0005 0006 0007 0008 0009 0010. (看在大括号扩展之前执行参数扩展?

答案1

那是因为 shell 评估了;,所以eval没有看到它。

您必须转义任何 shell 特殊字符以延迟其计算,并且 pass 的字面意思是eval

eval for i in \{"$1".."$2"\}\; do echo \"\$i\"\;  done

答案2

该行在第一个元字符处断开,即;(在本示例中)。
该行:

eval for i in {$1..$2}; do echo $i;  done

分为这样三个命令:

eval for i in {$1..$2};
do echo $i;
done

尝试do在没有先前的for, while,的情况下执行 auntil是行不通的。它将引发错误条件:

意外标记“do”附近出现语法错误

发生这种情况是因为前一个for作为参数隐藏在命令中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 和 $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'

相关内容