You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询:替代长串if/else,高效实现Bash风格信号终止消息打印

更高效的Bash信号终止消息实现方案

嘿,我完全懂你这种用一堆if/else堆出来的代码有多难受——不仅写起来麻烦,以后要加新信号或者修改消息也得翻半天。给你几个更高效优雅的方案,帮你把代码简化:

方案1:利用系统自带的strsignal()函数(推荐)

其实POSIX标准库已经提供了strsignal()函数,它可以直接把信号编号转换成对应的描述字符串,和Bash默认输出的消息完全一致,而且跨平台兼容性好,不用自己维护字符串列表。

代码示例:

#include <signal.h>
#include <stdio.h>
#include <string.h>  // 用于strsignal

void print_signal_termination(int status) {
    if (WIFSIGNALED(status) && WTERMSIG(status) != SIGINT) {
        int sig = WTERMSIG(status);
        const char *msg = strsignal(sig);
        
        // 如果有核心转储,追加"(core dumped)"
        if (WCOREDUMP(status)) {
            fprintf(stderr, "%s (core dumped)\n", msg);
        } else {
            fprintf(stderr, "%s\n", msg);
        }
    }
}

优点:

  • 零维护:不用手动对应每个信号和消息,系统帮你搞定
  • 兼容性强:符合POSIX标准,在Linux、BSD、macOS等系统都能正常工作
  • 效率高:底层实现通常是数组映射,O(1)查找速度

方案2:静态数组映射信号编号与消息

如果因为某些限制不能用strsignal()(比如非常古老的系统),可以用静态数组来做映射,把信号编号作为数组索引,直接对应到消息字符串,比if/else简洁太多。

代码示例(以Linux常见信号编号为例):

#include <signal.h>
#include <stdio.h>

// 按信号编号顺序排列,索引对应信号值
static const char *signal_msgs[] = {
    "",                  // 信号0无意义
    "Hangup",            // SIGHUP(1)
    "Interrupt",         // SIGINT(2) —— 我们会跳过它
    "Quit",              // SIGQUIT(3)
    "Illegal instruction",// SIGILL(4)
    "Trace/breakpoint trap",// SIGTRAP(5)
    "Aborted",           // SIGABRT(6)
    "Bus error",         // SIGBUS(7)
    "Floating point exception",// SIGFPE(8)
    "Killed",            // SIGKILL(9)
    "User defined signal 1",// SIGUSR1(10)
    "Segmentation fault",// SIGSEGV(11)
    "User defined signal 2",// SIGUSR2(12)
    "Broken pipe",       // SIGPIPE(13)
    "Alarm clock",       // SIGALRM(14)
    "Terminated"         // SIGTERM(15)
    // 可根据需要继续添加更多信号的消息
};

void print_signal_termination(int status) {
    if (WIFSIGNALED(status)) {
        int sig = WTERMSIG(status);
        if (sig == SIGINT) {
            return;
        }
        
        // 检查信号编号是否在我们的数组范围内
        if (sig >= 1 && sig < sizeof(signal_msgs)/sizeof(signal_msgs[0])) {
            if (WCOREDUMP(status)) {
                fprintf(stderr, "%s (core dumped)\n", signal_msgs[sig]);
            } else {
                fprintf(stderr, "%s\n", signal_msgs[sig]);
            }
        } else {
            fprintf(stderr, "Unknown signal (%d)\n", sig);
        }
    }
}

优点:

  • 完全可控:可以自定义消息内容,不受系统默认输出限制
  • 效率高:直接数组索引访问,O(1)查找
  • 代码简洁:比一堆if/else可读性强太多

注意事项

  • 不同系统的信号编号可能略有差异(比如BSD和Linux的部分信号编号不同),如果用数组方案,需要根据目标系统调整索引对应的消息
  • 别忘了处理WCOREDUMP(status)的情况,这和Bash的输出逻辑一致

内容的提问来源于stack exchange,提问作者Lazarus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:27:32