如果命令失败,终止管道其余部分的最简洁方法是什么?

奥登·奥尔森(Audun Olsen)

考虑以下:

command1 | command2 | command3

据我了解,流水线会运行每个命令,而不管可能发生的任何错误。当命令返回stderr时,它不会通过管道传递到下一个命令,但是下一个命令仍将运行(除非使用|&)。我想要终止其余管道可能发生的任何错误。我以为set -o pipefail可以做到这一点,但是如果管道中的任何内容失败,它只会终止管道之后可能发生的任何事情,即:

(set -o pipefail; cmd1 | cmd2 && echo "I won't run if any of the previous commands fail")

那么,如果任何一条命令失败,最简洁的方法是终止管道其余部分我还需要它以失败的命令的正确stderr退出。我是从命令行上下文而不是Shell脚本执行此操作的,因此,我为什么要简短一些。有什么想法吗?

菲利普·库林

我相信这是不可能的

我相信,由于管道的执行方式,您所要求的是不可能直接实现的。当外壳程序在管道中执行“稍后”命令时,外壳程序不知道命令的成功或失败(返回值)。它实际上同时运行所有它们,然后收集结果。

有一些变通办法可能会有所帮助。

解决方法1

一次执行一个命令并缓存结果。这样做会更好,因为如果先前的命令失败,则以后的命令绝对不会运行。

一个非常简短的脚本示例:

cache_file=`tempfile`
if command1 > $cache_file ; then
    command2 < $cache_file
fi
rm $cache_file

解决方法2

执行所有操作,但检查返回结果无论如何,此命令仍将运行所有命令,但确实可以让您返回原因。

在此,每个命令的STDERR使用重定向到一个不同的文件2>然后PIPESTATUS检查以找到每个命令的返回码。

command1 2> command1_err.log | command2 2> command2_err.log
for result in ${PIPESTATUS[@]} ; do
    if [ $result -ne 0 ] ; then
        echo command failed
    fi
done

在Shell中运行管道的简要概述

要创建管道,shell遵循这些步骤相似的步骤

  1. |使用pipe()创建每个管道()每个管道都带有一个读取句柄和一个写入句柄。对于每个重定向(<>),它将打开各自的文件,并使用open()获得该文件的句柄
  2. Shell对管道中的每个命令调用一次fork()以启动新进程。
  3. 每个子进程将其STDIN,STDOUT和STDERR句柄交换为在(1.)中创建的子进程。
  4. 假设命令是一个外部二进制文件,则每个子进程然后调用exec()来加载和运行二进制文件。
  5. 然后,父进程使用wait()等待子进程完成,该进程还提供命令的返回值(成功或失败)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

是什么停止了此查询的其余部分?

是否可以简化at命令的其余部分?

比较列表以检查它们是否具有部分匹配的最标准(/简洁)方法是什么?

Selenium/Testng:如果发生异常,则跳过或失败@Test 的其余部分

创建永不返回的任务的最简洁方法是什么?

将变量设置为getElementById的值或如果找不到该元素的默认值的最简洁方法是什么?

如果以给定字符开头,则返回变量的其余部分

如果InputQuery为false,则取消过程的其余部分

如果可以失败,从stdin读取几个int的最简单方法是什么?

为可能失败的备份命令处理stdout的最Unix-y方法是什么?

填写屏幕的其余部分

如何忽略其余部分?

野牛中的“其余部分”

页面其余部分的CSS

用序列中的列表值创建字典的最简洁(最Pythonic)方法是什么?

当解析器的一部分成功而其余部分失败时,为什么Parsec不回溯呢?

如果给出了原始图像,如何将photoshop的部分与图像的其余部分分开?

在 Python 对象上“转发”方法调用的最简洁方法是什么?

在Scala中构造/构建JavaBean对象的最简洁方法是什么?

使用Java 8,打印文件中所有行的最优选,最简洁的方法是什么?

使用Java 8,创建字符串的排序和分组列表的最简洁方法是什么

将变量传输到python string.format的最简洁方法是什么?

获得Java布尔值的倒数的最简洁方法是什么?

在Postgres中:在多个值上使用“ IS DISTINCT FROM”的最简洁方法是什么?

将命名参数传递给Golang工具并使用它们的最简洁方法是什么?

递归Goroutines,告诉Go停止从通道读取的最简洁的方法是什么?

使用Combine和SwiftUI显示变化值的最简洁方法是什么?

调用Java 8功能接口的最简洁的Scala方法是什么?

获取另一个属性指向的属性的最简洁的fp方法是什么