shell 使用代码块和管道退出代码
shell exit code with code-block and pipe
在 shell 脚本中,我使用带花括号的代码块将所有输出通过管道传输到控制台和带 tee 的日志文件。
#!/bin/bash
{
echo "Foo bar"
echo "foo bar on STDERR" >&2
ERRL=66
exit 99
} 2>&1 | tee log-file.log
(这只是一个小demo脚本,原来的要复杂得多)
问题是,行 exit 99
没有效果,脚本以退出代码 0 结束。(我认为这是 tee 命令的退出代码)
我试图在脚本末尾添加行 exit $ERRL
,但它显示变量 $ERRL 在大括号外为空。
我该怎么做,才能在代码块中出现问题时以错误代码结束脚本——而不会将输出丢失到日志文件?
那是因为退出代码是管道中的 last 命令之一,除非管道之前有 set -o pipefail
。由于 , the $PIPESTATUS
array 包含管道中每个命令的退出代码,与原始管道的顺序相同。
重定向整个脚本输出的侵入性最小的方法是预先执行一次,不涉及任何阻塞结构:
exec > >(tee log-file.log) 2>&1 # redirect stdout and stderr to a pipe to tee
echo "Foo bar"
echo "foo bar on STDERR" >&2
ERRL=66
exit 99
替代选项包括使用 pipefail
设置...
set -o pipefail
{ ... } 2>&1 | tee log-file.log
...或事后显式退出退出状态:
{ ... } 2>&1 | tee log-file.log
exit "${PIPESTATUS[0]}"
...或仅使用不是管道的重定向:
{ ... } > >(tee log-file.log) 2>&1
在 shell 脚本中,我使用带花括号的代码块将所有输出通过管道传输到控制台和带 tee 的日志文件。
#!/bin/bash
{
echo "Foo bar"
echo "foo bar on STDERR" >&2
ERRL=66
exit 99
} 2>&1 | tee log-file.log
(这只是一个小demo脚本,原来的要复杂得多)
问题是,行 exit 99
没有效果,脚本以退出代码 0 结束。(我认为这是 tee 命令的退出代码)
我试图在脚本末尾添加行 exit $ERRL
,但它显示变量 $ERRL 在大括号外为空。
我该怎么做,才能在代码块中出现问题时以错误代码结束脚本——而不会将输出丢失到日志文件?
那是因为退出代码是管道中的 last 命令之一,除非管道之前有 set -o pipefail
。由于 $PIPESTATUS
array 包含管道中每个命令的退出代码,与原始管道的顺序相同。
重定向整个脚本输出的侵入性最小的方法是预先执行一次,不涉及任何阻塞结构:
exec > >(tee log-file.log) 2>&1 # redirect stdout and stderr to a pipe to tee
echo "Foo bar"
echo "foo bar on STDERR" >&2
ERRL=66
exit 99
替代选项包括使用 pipefail
设置...
set -o pipefail
{ ... } 2>&1 | tee log-file.log
...或事后显式退出退出状态:
{ ... } 2>&1 | tee log-file.log
exit "${PIPESTATUS[0]}"
...或仅使用不是管道的重定向:
{ ... } > >(tee log-file.log) 2>&1