如果一切顺利,我试图让 bash 脚本保持沉默,但如果由于某种原因崩溃,则打印出所有 stderr 和调试信息。以下是我到目前为止所拥有的。
#!/usr/bin/bash
set -e
rm -f /tmp/err
trap "sleep 1 && cat /tmp/err" ERR
l() {
ts >> /tmp/err
}
echo "About to download stuff:" > >(l)
# curl blah blah 2> >(l)
# something goes wrong in the script
invalid_cmd
只有当我有我不喜欢的“睡眠 1”时它才能正常工作。
不睡觉:
❯ ./demo2.sh
./demo2.sh: line 18: invalid_cmd: command not found
与睡眠:
❯ ./demo2.sh
./demo2.sh: line 18: invalid_cmd: command not found
Feb 25 15:20:44 About to download stuff:
我认为这是因为进程替换在后台运行并且可能无法完成。我也不想盲目地wait
执行所有后台任务。有更好的方法来解决这个问题吗?
答案1
经过更多的黑客攻击后,找到了以下解决方案。
#!/usr/bin/bash
set -e
make_temp_fds() {
local tfile=$(mktemp)
exec {fdw}>$tfile {fdr1}<$tfile {fdr2}<$tfile
rm $tfile
}
setup_err_fd() {
make_temp_fds
local raw_fdw=$fdw raw_fdr=$fdr1
make_temp_fds
local ts_fdw=$fdw ts_fdr=$fdr1
ts <&$raw_fdr >&$ts_fdw &
tspid=$!
trap "wait $tspid && cat <&$ts_fdr" ERR
err_fd=$raw_fdw
}
# Calling this function, will give you $err_fd
# Anything written to $err_fd will be saved in a temporary file with timestamps
# and printed out if the script fails with an error.
# Will be lost if script exits successfully
setup_err_fd
echo "all setup"
echo "debug line 1" >&$err_fd
echo "debug line 2" >&$err_fd
not_ok
#echo "ok"
echo "bye"
不幸的是它涉及两个临时文件。我试图将其中一个制作成管道,但无法正常工作。随时改进