我有一个包含unix命令列表的文件,例如“ls -la / etc / passwd”。我想迭代这个命令列表,并采取适当的措施。
目前,我的代码类似于:
#!/bin/bash
clear
for cmds in `cat /tmp/cmd`
do
if [ $cmds ] ; then
echo $cmds;
fi
done
但是,我得到的是一个输出,其中命令被分解为不同的行,如
ls
-la
/etc/passwd
ls
-la
/etc/shadow
而不是
ls -la /etc/passwd
ls -la /etc/shadow
有什么想法吗?
答案 0 :(得分:2)
在for循环之前添加:
IFS='
'
或者在Bash:
IFS=$'\n'
IFS
包含用于将输入拆分为字段的字符列表;它默认包含空格,制表符和换行符,这就是您获得错误行为的原因。将其设置为换行符只会在换行符上拆分,这就是您想要的。
答案 1 :(得分:2)
我相信你也可以这样做(用双引号包围你的反引号):
"`cat /tmp/cmds`"
也许尝试这样的事情(不确定你的“if”应该检查什么 - 我修改它以确保$ cmds var不是空字符串):
#!/bin/bash
clear
for cmds in "`cat cmds.txt`"
do
if [ "$cmds" != '' ]; then
echo "$cmds"
fi
done
答案 2 :(得分:2)
如果文件中的每一行都是一个完整的命令 - 没有连续多行 - 那么你可以使用read
:
while read cmd
do
if [ -z "$cmd" ]
then : Empty
elif $cmd
then : OK
else : Oops
fi
done < cmds.txt
或者,如果您更喜欢线性构造,并且不需要while循环代表的子shell中的任何内容,您可以使用:
cat cmds.txt |
while read cmd
do
if [ -z "$cmd" ]
then : Empty
elif $cmd
then : OK
else : Oops
fi
done
请注意在测试字符串周围仔细使用引号。我仍然喜欢使用明确的“-z
”运算符;有些人认为这不是100%必要的。我仍然使用单方括号而不是双倍 - 主要是出于20多年的习惯。那些使用bash
或ksh
学习shell的人通常更喜欢使用双方括号运算符。
当然要注意I / O重定向。
此外,如果您在各种then和else子句中没有任何操作,则只需将cmds.txt提供给shell:
sh cmds.txt
这是目前处理多行命令最可靠的方法。