显示或重定向shell的作业控制消息 [英] Displaying or redirecting a shell's job control messages

查看:25
本文介绍了显示或重定向shell的作业控制消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这适用于正常程序,但有一个问题,即外壳程序的作业控制消息(例如,从段故障生成的那些消息)不会出现。

举例:

% 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、使用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打印的,而不是失败的进程,所以如果您尝试重定向stdoutstderr,作业消息将不会重定向。

因此,一方面,如果您尝试从正在运行的进程中提取有用的输出并将其重定向到其他地方,则不需要担心作业消息会妨碍您。但这也意味着,如果您尝试通过重定向stderr来重定向,您将不会收到SEGERFAULT消息。

以下是此效果的演示,为清楚起见,在命令之间添加了换行符:

% 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's documentation on jobs and signals。您也可以四处查看the C file where the magic happens

这篇关于显示或重定向shell的作业控制消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆