当像 sed 或 tee 这样的管道时,Bash 管道会吞下退出代码

问题描述 投票:0回答:1

我正在使用名为

turbo prune
的 Turbo 功能,它会创建文件夹
out
以及我的 monorepo 的部分副本,但不幸的是,这意味着在 GitHub Actions 中运行像
turbo run lint
这样的命令时,将打印出其中包含
out
的路径(从而破坏了常规的 github 错误报告),所以我没有使用这个命令:

turbo run lint

我尝试将其替换为:

turbo run lint | sed 's/\/out//g'

它输出正确的路径,但我的 lint 检查总是通过,因为即使

turbo
以退出代码 1 退出,但
sed
以 0 退出。

bash shell sed pipe tee
1个回答
0
投票

TL;博士:

(set -o pipefail && <your command>)

答案

我一直在四处寻找,找到了这个问题的一些答案。我将从最短的开始,将您的

turbo run lint | sed 's/\/out//g'
替换为:

(set -o pipefail && turbo run lint | sed 's/\/out//g')

这会将您的 shell 切换到退出代码不再被管道操作符吞没的模式(仅针对这一命令)。如果您不介意将整个脚本切换到此模式,您可以跳过使用子 shell 并执行以下操作:

set -o pipefail 
turbo run lint | sed 's/\/out//g'

顺便说一句:更一般的建议是始终启动这样的bash脚本以获得最佳的错误处理:

#!/usr/bin/env bash
set -eo pipefail

现在为了完整起见,你也可以使用这样的东西:

turbo run lint | sed 's/\/out//g'
exit ${PIPESTATUS[0]

如果您出于某种原因不想使用子 shell,但想恢复管道中退出代码的默认处理,您可以使用此解决方案

set -o pipefail 
turbo run lint | sed 's/\/out//g'
set +o pipefail 

这个问题甚至有更奇特的解决方案,但说实话,我看不出有什么吸引力。

© www.soinside.com 2019 - 2024. All rights reserved.