在命令管道cmd1 | cmd2 | cmd3中,成功/失败状态的传递机制非常特殊:默认情况下,只有最后一个命令的退出状态会作为整个管道的退出状态,中间命令的失败状态会被"隐藏"。
=====================================================
注:其实很好理解,因为管道就是一个数据传输流,而不是状态传输链。状态不会被传递,所以只有最后一个命令的执行状态会保留。
=====================================================
管道状态传递机制对比
| 场景 | 管道示例 | 整体退出状态$? | 关键问题 |
|---|---|---|---|
| 默认情况 | cmd1 | cmd2 | cmd3 | 仅cmd3的退出状态 |
管道仍可能"成功" |
bash的PIPESTATUS | cmd1 | cmd2 | cmd3 | 数组存储每个命令的退出状态 | bash特有,且会被下一条命令 覆盖 |
set -o pipefail | cmd1 | cmd2 | cmd3 | 任一命令失败则整个管道失败 | 需要主动设置,仅获取首个失败 状态 |
三种状态获取方式验证
实验环境:GNU bash,版本 4.4.20(1)-release (x86_64-Anolis-linux-gnu)
1. 默认情况:只看最后一个命令
2. bash特有:PIPESTATUS数组
3. 使用pipefail选项:任一失败则整个失败
大家可以根据实际需求,使用不同场景,以满足需要。最后,下一篇会详细介绍一下“管道”~~~敬请期待。