bash 中的逻辑全部/任意

bash 中的逻辑全部/任意

我想运行一系列测试(每个测试都在不同的 PID 上),并且仅当所有测试成功退出时才得出成功状态。就像是

check $PID1 && check $PID2 && check $PID3

但对于不确定数量的测试。我怎样才能做到这一点?

答案1

将其写为循环应该不会太难:

pids=(1025 3425 6474)
check_all() {
    for pid in "$@"; do
        if ! check "$pid"; then
            return 1
        fi
    done
}
check_all "${pids[@]}"

与链接的命令链一样&&,该功能将在第一次失败时停止check

但请注意,我用单个数组替换了您的变量等PID1PID2Bash 可以迭代名称以特定字符串开头的变量,但数组更方便。 (除非这些变量来自脚本外部,通过无法传递正确数组的环境。)

check另外,我在这里对循环中的命令进行了硬编码。您可以传递不同的命令来运行函数,但这会带来分词和引号处理的问题。 (看这里这里.)

答案2

您可以将其放入带有错误退出 ( -e) 的子 shell 中:

pids=(1025 3425 6474)
(
    set -e
    for pid in "${pids[@]}"; do
        check "$pid"
    done
)
echo $?

|| exit 1或者,您可以使用set -e

pids=(1025 3425 6474)
(
    for pid in "${pids[@]}"; do
        check "$pid" || exit 1
    done
)
echo $?

答案3

或许:

parallel -j0 check ::: $pid1 $pid2 $pidN &&
  echo all succeeded
parallel -j0  '! check' ::: $pid1 $pid2 $pidN &&
  echo all failed
parallel -j0 --halt soon,success=1 check ::: $pid1 $pid2 $pidN &&
  echo one succeeded
parallel -j0 --halt soon,fail=1 check ::: $pid1 $pid2 $pidN ||
  echo one failed

它将并行运行检查。如果您希望在我们知道结果后立即终止正在运行的检查,请替换soon为。now

如果您将 PID 作为管道的输出(每行一个):

pid_generator | parallel -j0 check && echo all succeeded

parallel给一个值并并行运行尽可能check多的值( )。check-j0

如果尚未parallel安装服务器,请在具有以下功能的计算机上运行它: parallel安装:

parallel --embed > new_script

编辑new_script(最后 5 行)并将脚本复制到服务器。

答案4

一个简单的函数可以测试每个参数;如果失败,则从函数返回一个非零代码:

#!/bin/sh

testall() {
  for test
  do
    sh -c "$test" || return 1
  done
}

通过一些示例测试:

$ testall "echo 1" "echo 2" "false" && echo all OK
1
2
$ testall "echo 1" "echo 2" "echo 3" && echo all OK
1
2
3
all OK
$ testall && echo all OK
all OK

相关内容