我对 for 循环中的范围变量有疑问。在 for 循环中,我知道您可以使用 {..} 来定义范围。但我希望它是客户可定义的。所以脚本要求一个范围值,我希望它是灵活的。像这样:
#!/bin/bash
while true;
do
echo "Some explenation..."
read -p "Possible values are: ALL or RANGE (to define a specific range):" answer
case $answer in
#ALL
[aA][lL][lL] )
echo "ALL is selected, 1 to 250"
RANGE="{1..250}"
break
;;
#RANGE
[rR][aA][nN][gG][eE] )
echo "Range is selected, please define a custom range. Notation should be like: <start>..<stop>"
echo "or: <single> <single>"
echo "or a combination of both. Like: 1..23 28 29 101..145 180 212"
read RANGE
break
;;
#OTHERS
* )
echo "Typo error!! Not correct, type again ALL, PRI, SEC or
RANGE"
;;
esac
done
echo ""
echo "Range for this execution is set to:"
echo "$RANGE"
for NEXI in $RANGE
do
sleep 0.2
echo "Nexus number: $NEXI"
done
echo ...
但是当我输入 {1..10} 52 54 {120..128} 时的输出是:
Nexus number: {1..10}
Nexus number: 52
Nexus number: 54
Nexus number: {120..128}
虽然我期望它是这样的:
Nexus number: 1
Nexus number: 2
Nexus number: 3
Nexus number: 4
Nexus number: 5
Nexus number: 6
Nexus number: 7
Nexus number: 8
Nexus number: 9
Nexus number: 10
Nexus number: 52
Nexus number: 54
Nexus number: 120
Nexus number: 121
... etc.
完全写出来了。
我可以改变什么来实现这个目标?
谢谢。
答案1
问题是大括号扩展发生在变量扩展之前。正如中所解释的man bash
:
展开的顺序是:大括号展开;波形符扩展、参数和变量扩展、算术扩展和命令替换(以从左到右的方式完成);分词;和路径名扩展。
这意味着当您有类似$var
which contains{1..3}
和 do 的内容时echo "$var"
,shell 会查找可能的大括号扩展前将变量扩展为其值。由于大括号位于变量中,这意味着此时 shell 看不到大括号,因此不会执行大括号扩展。
eval
如果变量是一个范围,则一种解决方法是对其进行处理。在循环之前添加这些行for
:
if [[ $RANGE =~ ^[0-9]+\.\.[0-9]+$ ]]; then
RANGE=$(eval echo {$RANGE})
fi
现在,更一般地说,避免在 shell 脚本中使用大写变量名通常是个好主意。环境变量通常是大写的,如果您碰巧使用与定义的环境变量相同的名称,则可能会导致混淆。因此,为了安全起见,请使用小写变量名。
另外,这是一个调试起来非常烦人的程序,使用起来也同样烦人。不要在运行时提示用户输入!相反,更改您的脚本并使其接受参数。输入值很困难、烦人、容易出错并且无法自动化。
答案2
将您的 shell 设置为ksh
,此代码应该可以工作。
#!/usr/bin/ksh