1

我刚刚注意到,即使编译失败,我的一些 CI 作业也返回了 OK。这本质上是因为调用 bash 命令来编译代码,虽然失败并返回 1,但它的输出通过管道传输sed以向输出添加一些颜色等。

本质上,这归结为以下几点

$ false; echo $? # returns 1
$ true; echo $? # returns 0
$ false | sed 's/^/OUTPUT: /' # returns 0 because sed returns 0
$ true | sed 's/^/OUTPUT: /' # returns 0 because sed returns 0

我知道在 bash 上有PIPESTATUS,所以我可以${PIPESTATUS[0]}用来获取在管道之前运行的命令的退出代码。但是如何围绕任何命令进行包装,以便将其输出通过管道传输到 sed,然后返回命令本身的退出代码(丢弃 的退出代码sed)?

为了使它真正通用,假设我想将任何命令的输出通过管道传输到 sed 以在每行输出之前添加一个彩色前缀:

$ PREFIX="$(printf '\033[1;31m')OUTPUT: $(printf '\033[0m')"
$ ls | sed "s/^/$PREFIX/"

如上所述,由于管道 to sed,无论返回什么都将返回 0 ls,并且将显示目录内容,每行前面都有一个红色OUTPUT:

我可以定义一个函数、别名等(我们称之为“wrap”)来让我调用,例如wrap ls *.txt,以这样一种方式ls *.txt执行,输出通过 sed 模式传输,并ls *.txt返回其自身的退出代码,这样

$ wrap ls *.txt
OUTPUT: file1.txt
OUTPUT: file2.txt
$ echo $? # displays 0 (assuming there is at least one .txt file)
$ wrap ls *.foo
ls: No such file or directory
$ echo $? # displays 1 (assuming there is NO .foo file)
4

1 回答 1

1

尝试:

function wrap
{
    "$@" | sed 's/^/OUTPUT: /'
    return "${PIPESTATUS[0]}"
}
于 2021-02-17T16:21:26.353 回答