通过管道将 main 方法传递给 tee 将使 trap 方法看不到全局变量
我有一个 trap 方法,它既不访问全局变量,也不使用 $*
接收变量。它看起来像这样:
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
declare -a arr
finish_exit() {
echo "* = $*"
echo "arr = ${arr[*]}"
}
trap 'finish_exit "${arr[@]}"' EXIT
main() {
arr+=("hello")
arr+=("world")
}
main | tee -a /dev/null
脚本打印“”。
如果我删除 | tee -a ...
片段,脚本按照预期打印 'hello\nworld' 两次。
现在,如何将输出通过管道传输到日志文件而不丢失所有上下文? 一种解决方案是路由脚本调用中的所有内容,如下所示: <代码>./myscript.sh>> /dev/null,但我认为应该有一种方法可以在脚本中执行此操作,这样我就可以记录每个调用,而不仅仅是那些由 cron 运行的调用。
我研究的另一个解决方案是:
main() {
...
} >> /dev/null
但这将导致交互式 shell 上没有输出。
解释为什么这个子 shell 会在调用 trap 函数之前“擦除”全局变量的额外业力。
I have a trap method which neither access global variables nor receive variables using $*
. It looks like this:
#!/usr/bin/env bash
set -euo pipefail
IFS=
The script prints ''.
If I remove the | tee -a ...
snippet, the script prints 'hello\nworld' twice as expected.
Now, how can I pipe the output to a logfile WITHOUT loosing all context?
One solution would be to route everything from the script call, like so:
./myscript.sh >> /dev/null
, but I think there should be a way to do this inside the script so I can log EVERY call, not just those run by cron.
Another solution I investigated was:
main() {
...
} >> /dev/null
But this will result in no output on the interactive shell.
Bonus karma for explanations why this subshell will "erase" global variables before the trap function is being called.
\n\t'
declare -a arr
finish_exit() {
echo "* = $*"
echo "arr = ${arr[*]}"
}
trap 'finish_exit "${arr[@]}"' EXIT
main() {
arr+=("hello")
arr+=("world")
}
main | tee -a /dev/null
The script prints ''.
If I remove the | tee -a ...
snippet, the script prints 'hello\nworld' twice as expected.
Now, how can I pipe the output to a logfile WITHOUT loosing all context?
One solution would be to route everything from the script call, like so:./myscript.sh >> /dev/null
, but I think there should be a way to do this inside the script so I can log EVERY call, not just those run by cron.
Another solution I investigated was:
But this will result in no output on the interactive shell.
Bonus karma for explanations why this subshell will "erase" global variables before the trap function is being called.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
子 shell 确实“看到”全局变量,但它不执行 trap。
从https:// “删除”全局变量www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html:
或
研究:https://serverfault.com/questions/ 103501/how-can-i-complete-log-all-bash-scripts-actions 和类似的。
以下脚本:
为我输出:
我在管道之前添加了
set -o pipelinefail
,以保留退出状态。The subshell does "sees" global variables, it does not execute the trap.
From https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html :
or
And research: https://serverfault.com/questions/103501/how-can-i-fully-log-all-bash-scripts-actions and similar.
The following script:
outputs for me:
I added that
set -o pipefail
before the pipe, to preserve the exit status.