在Shell编程中迭代文件中的命令列表

时间:2009-04-13 23:45:32

标签: shell

我有一个包含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

有什么想法吗?

3 个答案:

答案 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多年的习惯。那些使用bashksh学习shell的人通常更喜欢使用双方括号运算符。

当然要注意I / O重定向。

此外,如果您在各种then和else子句中没有任何操作,则只需将cmds.txt提供给shell:

sh cmds.txt

这是目前处理多行命令最可靠的方法。