BASH变量具有多个命令和可重入

时间:2009-07-13 18:21:47

标签: bash shell command

我有一个bash脚本从另一个文件中获取内容。另一个文件的内容是我想要执行的命令并比较返回值。有些命令有多个命令由分号(;)或&符号(&&)分隔,我似乎无法使其工作。为此,我创建了一些测试脚本,如下所示:

test.conf是由test

提供的文件

示例-1(这可行),我的输出差异为2秒

test.conf

    CMD[1]="date"

test.sh

    . test.conf
    i=2
    echo "$(${CMD[$i]})"
    sleep 2
    echo "$(${CMD[$i]})" 

示例-2(这不起作用) test.conf(与上面相同的脚本)

    CMD[1]="date;date"

示例-3(试过这个,它也不起作用) test.conf(与上面相同的脚本)

    CMD[1]="date && date"

我不希望我的变量CMD位于刻度内,因为这样,命令将在调用源时执行,我看不到重新评估变量的方法。

这个脚本本质上调用pass-1上的CMD来检查一些东西,如果在pass-1上我得到一个错误的读数,我在脚本中做了一些工作来纠正错误读取并重新执行&重新评估CMD的输出;通过-2。

这是一个例子。在这里,我正在检查SSHD是否正在运行。如果我在pass-1上评估CMD [1]时它没有运行,我将启动它并再次重新评估CMD [1]。

test.conf

    CMD[1]=`pgrep -u root -d , sshd 1>/dev/null; echo $?`

因此,如果我为我的测试脚本修改了这个,那么test.conf就会变成: 注意:刻度线标记没有显示,但它是键盘上〜标记下方的键。

    CMD[1]=`date;date` or `date && date`

我的脚本看起来像这样(处理刻度线)

    . test.conf
    i=2
    echo "${CMD[$i]}"
    sleep 2
    echo "${CMD[$i]}"

尽管延迟了2秒,但我得到了相同的日期/时间。因此,CMD没有得到重新评估。

2 个答案:

答案 0 :(得分:1)

从问题的几个方面来看,我本来期望这样的方法:

#!/bin/bash

while read -r line; do
    # munge $line
    if eval "$line"; then
        # success
    else
        # fail
    fi
done

如果你在源代码中有反引号,你必须逃避它们以避免过早地评估它们。此外,反引号不是评估代码的唯一方法 - 有eval,如上所示。也许你正在寻找eval

例如,这一行:

CMD[1]=`pgrep -u root -d , sshd 1>/dev/null; echo $?`

应该看起来更像这样:

CMD[1]='`pgrep -u root -d , sshd 1>/dev/null; echo $?`'

答案 1 :(得分:1)

首先,除非您需要与不支持$() - 且仅支持的旧shell兼容,否则不应使用反引号。

其次,我不明白为什么要设置CMD[1],然后在CMD[$i]设置为i的情况下调用2

无论如何,这是一种方式(它与Barry的答案相似):

CMD[1]='$(date;date)'    # no backticks (remember - they carry Lime disease)
eval echo "${CMD[1]}"    # or $i instead of 1