Shell脚本中使用变量作为for循环范围

Shell脚本中使用变量作为for循环范围,第1张

我们知道在shell脚本中,可以通过 {xy} 这样的表达式来表示一个从x到y的数列

这个用法在shell脚本里叫做 Brace Expansion 。

因此我们常利用这个表达式来作为循环的次数,如:

可以得到从1到10的输出结果。

但是如果我们想输出从1到一个变量的结果,这个变量从其他地方获取:

得到的结果却是

放弃使用 {xy} 这样的表达式:

seq 命令的原理就不说了,这里说说为什么不能在 { } 中使用变量。其实原因写在bash的man手册中:

Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result It is strictly textual Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces

大意是说,Bash中会最先展开 { } 中的内容,这个时候 $NUM 还不会被具体的值替代,所以是 i 在循环中读取的是 ‘{1$NUM}’ 的一个完整的字符串,输出时 $NUM 会被10替代,就有了 '{110}' 这样的结果。

关于Bash中的展开 (expansion) 顺序,其实有不少值得注意的地方,一不留神可能就会踩坑,还是老前辈那句:脚本猛于虎。

time=3600
unixbench &//运行的程序
pid=$!
for((i=0;i<3600;i++))
do
sleep 1
done
kill -9 $pid

a=`date`
b=`who|awk '{printf $1 "\n"}`
echo "$b\n" > btxt
while [ 1 -lt 2 ]
do
echo "The current time is :$a"
echo "The current users are :$b"
sleep 30
c=`who|awk '{printf $1 "\n"}`
echo "$c\n" > ctxt
echo `awk '{print $0}' btxt ctxt|sort|uniq -u` > tmpfile
d=`cat tmpfile|grep -v ^$|wc -l`
if [ $d -eq 0 ]
then
echo "no user login and logout"
else
i=1
while [ i -le $d ]
do
e=`cat tmpfile|awk '{printf $0 " "}'|awk '{printf $k}' k="$i"`
if [ `cat btxt|grep $e|wc -l` -eq 0 ]
then
echo "user login:$e"
else
echo "user logout:$e"
fi
let i=i+1
done
fi
echo "$c\n" > btxt
done

while [ $c != "1" && $c != "2" ]

改成

while [[ $c != "1" && $c != "2" ]]

或者

while [ $c != "1" -a $c != "2" ]

另外,如果像这样是输入1或者2,建议换成 select 语句。

[ $ -eq 0 ] && echo '成功' || echo '失败'
[root@centos~]# ls
anaconda-kscfg installlog installlogsyslog rpmbuild
[root@centos~]# [ $ -eq 0 ] && echo '成功' || echo '失败'
成功
[root@centos~]# lsss
-bash: lsss: command not found
[root@centos~]# [ $ -eq 0 ] && echo '成功' || echo '失败'
失败
[root@centos~]#

按键精灵的无限循环,有多种实现方式。常见的是设为while句式、goto句式、Do 循环句式。

针对脚本本身的无限循环,在“脚本循环”中,选择“循环到按中止键为止”。

以按键精灵9脚本为例:

1、while句式。

i=0

While i=0

Msgbox "我停不下来啦!!快住手"

Wend

//当循环条件成立的时候,反复执行循环体

2、goto句式。

Goto 标记

Delay 100

Rem 标记

Msgbox "你直接跳到这里了!!,上面的延迟没有被执行!!"

//跳转语句,可以跳转到rem标记过的标记处继续执行

3、Do 循环句式。

i = 0

Do

MessageBox "ok"

Loop While i <> 0

//条件放后面,前面的循环内容可以执行一次!

4、如果仅是为了能无限循环执行脚本,可以在“脚本属性”中,点击“脚本循环”右侧”“。

5、选择“循环到按中止键为止”,这样脚本就会无限循环。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13405741.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-30
下一篇 2023-07-30

发表评论

登录后才能评论

评论列表(0条)

保存