如何为任意 bash 命令编写包装器?

How to write a wrapper for an arbitrary bash command?

我想在整个脚本中多次使用以下构造:

tries=0
while ! resposta=$(ssh ${nodes[$k]} 'nproc && uptime'); do
    let tries+=1
    if ((tries > max_tries)); then
        printf "Can't connect to %s !!!" "${nodes[$k]}"
        exit 1
    fi
    printf "Failed! Trying again after %d seconds...\n" "$sleep_time"
    sleep $sleep_time
done

此代码多次运行 resposta=$(ssh ${nodes[$k]} 'nproc && uptime') 命令,直到成功或达到最大尝试次数。

但是,有很多命令我想像上面的那样包含在一个块中。我现在正在做的是:每次需要时重复整个块,更改构成 while 循环条件的命令。

这当然是嘘声和愚蠢。不过,我想避免基于 eval 的解决方案——除了破坏语法高亮显示之外,更愚蠢的原因是 eval 是邪恶的 :)

您可以编写一个函数,将您想要 运行 的命令作为带引号的参数:

function repeat() {
    tries=0
    while ! resposta=$(); do
        let tries+=1
        if ((tries > max_tries)); then
            printf "Command %s failed" ""
            exit 1
        fi
        printf "Failed! Trying again after %d seconds...\n" "$sleep_time"
        sleep $sleep_time
    done
}

repeat "ssh ${nodes[$k]} ''nproc && uptime''"

请注意,字符串在传入时会被引用,以避免对其进行解释,但在扩展为 </code> 时不会被引用,以便实际调用该命令。</p> <p>另外,请注意双引号。这告诉 bash 在传递给函数的字符串中使用实际的单引号字符。否则,单引号将被删除,您将从服务器收到以下错误:</p> <pre><code>bash: nproc & uptime: command not found