使用trap时如何捕获Bash函数的stderr及返回码用于验证
问题描述
我有一个会在特定场景下报错的函数,希望编写测试代码验证它在这些场景下是否正常报错。简化后的函数所在文件内容如下:
set -e will_error() { echo "error" >&2 exit 100 }
我需要捕获该函数的stderr输出并与预期内容对比,同时还要验证它的返回码是否正确。当前测试代码如下:
test_no_default_no_argument() { trap ':' EXIT result=$(will_error 2>&1) if [ "$result" != "error" ];then echo "test failed" exit 1 fi } test_no_default_no_argument
请问如何同时捕获will_error函数的输出内容和返回码,用于后续验证?
解决方法
可以通过以下方式实现同时捕获输出内容与返回码的需求:
捕获输出后立即保存返回码
$?变量会保存上一条命令的退出状态码,在捕获子shell输出后立刻读取这个变量,就能拿到will_error函数的返回码,且不会被后续命令覆盖。完善测试验证逻辑
修改后的测试函数可以同时验证输出内容和返回码,示例代码如下:
test_no_default_no_argument() { # 临时关闭set -e,避免子shell的非零退出触发整个脚本退出(若测试脚本引入了带set -e的函数文件) set +e # 将stderr重定向到stdout,捕获函数输出到result变量 result=$(will_error 2>&1) # 立即保存函数的退出码 exit_code=$? # 恢复set -e(若之前开启了该选项) set -e # 验证输出内容是否符合预期 if [ "$result" != "error" ]; then echo "test failed: 输出内容不符合预期" exit 1 fi # 验证返回码是否符合预期 if [ "$exit_code" -ne 100 ]; then echo "test failed: 返回码不符合预期(实际为$exit_code,预期为100)" exit 1 fi echo "test passed" } test_no_default_no_argument
关键细节说明
set +e:临时关闭set -e选项,防止子shell中will_error的exit 100触发整个测试脚本直接退出,测试完成后可通过set -e恢复原配置。exit_code=$?:必须紧跟在捕获输出的命令之后执行,否则后续任何命令都会覆盖$?的值,导致无法获取正确的返回码。- 分两次验证:分别确认错误输出内容和返回码都符合预期,确保函数在报错场景下的行为完全符合要求。
内容的提问来源于stack exchange,提问作者fullinator
相关产品推荐
相关产品推荐

