我有这个脚本(test.sh):
#!/bin/bash
set -o errtrace
trap 'echo $BASH_VERSION >&2' ERR
echo <(cat<<EOF
Hello world
EOF
)
Run Code Online (Sandbox Code Playgroud)
运行它,我得到:
~/tmp$ bash test.sh
/dev/fd/63
~/tmp$ 5.0.18(1)-release
Run Code Online (Sandbox Code Playgroud)
两个问题:
为什么会触发 ERR 陷阱?
为什么5.0.18(1)-release在下一个提示之后,而不是在它之前
您的cat退出副本以非零退出状态退出,因为它无法将其输出写入 stdout(因为在父 shell 中运行的代码中没有任何内容实际上从 中读取 /dev/fd/63)。为运行该副本而生成的子shell 会cat记录一个错误。由于errtrace导致您的 ERR 处理程序在子外壳和其他上下文中使用,因此这会导致进程替换的子外壳调用处理程序。
因为这个进程替换是在子 shell 中运行的,所以它与脚本的其余部分是异步的;并且cat仅在echo退出后才给出错误(因为仅在那时关闭了 FIFO 的读取端,因此 cat 尝试将结果写入 SIGPIPE)。