咨询:替代长串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
相关产品推荐
相关产品推荐

