TL;DR
所有作业控制/崩溃消息在函数内出现时都会被隐藏。我将在下面详细介绍,但是@Barmar指出可以通过在函数内运行崩溃的二进制文件来重现此问题,例如:
crun() {
/tmp/faulty $1 $2 $3
}
我在我的中定义了一个函数.zshrc
使用以下函数编译并运行源代码:
crun() {
local file=$1
shift
local exepath="$(mktemp)"
if [[ $file =~ "\.c$" ]]; then
gcc -g -Wall $file -o $exepath || return $?
else
echo "no filetype detected"
return 126
fi
$exepath "$@"
}
可以用这种方式调用:
% crun source.cc arg_1 arg_2
这适用于普通程序,但存在一个问题,即 shell 的作业控制消息(例如由段错误生成的消息)不会出现。
举个例子:
% echo 'int main=0;' >> /tmp/faulty.c # a crashing c program
% crun faulty.c
% # no output generated
而等效的交互式命令将生成以下内容:
% g++ faulty.c -o /tmp/faulty && /tmp/faulty
[1] 2894 segmentation fault (core dumped) # ???? zsh's job control output for SIGSEGV
对于路径是动态计算的崩溃可执行文件,是否有任何方法可以显示这些消息?理想情况下无需编写自己的陷阱/信号处理程序 +exec
, using sh -c "$exepath $@"
,或者写一个全新的system(3)
完全包装)
你可以得到zsh
如果您将作业作为后台作业启动,然后立即将其带到前台,则打印作业中的分段错误消息。
"$exepath" "$@" &
fg
这会导致zsh
打印出有关开始的作业的信号消息$exepath
.
缺点是你得到的会比你讨价还价的多一点:
% crun faulty.c
faulty.c:1:5: warning: ‘main’ is usually a function [-Wmain]
int main=0;
^~~~
[2] 2080
[2] - running "$exepath" "$@"
zsh: segmentation fault (core dumped) "$exepath" "$@"
但如图所示,您将在终端中打印段错误消息。
由于消息是由交互式 shell 打印的,而不是由失败的进程打印的,因此如果您尝试重定向,作业消息将不会被重定向stdout
or stderr
.
因此,一方面,如果您尝试从正在运行的进程中获取有用的输出并将其重定向到其他地方,则无需担心作业消息会妨碍。但这也意味着如果您尝试通过重定向来重定向它,您将不会收到段错误消息stderr
.
以下是此效果的演示,为了清楚起见,在命令之间添加了换行符:
% crun good.c > test
[2] 2071
[2] - running "$exepath" "$@"
% cat test
Hello, world!
% crun faulty.c 2>test
[2] 2092
[2] - running "$exepath" "$@"
zsh: segmentation fault (core dumped) "$exepath" "$@"
% cat test
faulty.c:1:5: warning: ‘main’ is usually a function [-Wmain]
int main=0;
^~~~
有关更多信息,请参阅zsh有关作业和信号的文档。你也可以去逛逛神奇发生的 C 文件.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)