Har*_*rry 12 linux bash signals external bash-trap
在Linux上,是否有可能以某种方式禁用外部程序的信令...即,不修改其源代码?
语境:
我在Linux上的bash脚本中调用了一个C(也是一个Java)程序.我不希望我的bash脚本和脚本启动的其他程序(作为前台进程)中断.
虽然我可以用...
trap '' INT
Run Code Online (Sandbox Code Playgroud)
...在我的bash脚本中禁用Ctrl C信号,这仅在程序控件恰好在bash代码中时才有效.也就是说,如果我在C程序运行时按下Ctrl C,C程序会被中断并退出!这个C程序正在进行一些关键操作,因此我不希望它被中断.我无法访问此C程序的源代码,因此C程序内的信号处理是不可能的.
#!/bin/bash
trap 'echo You pressed Ctrl C' INT
# A C program to emulate a real-world, long-running program,
# which I don't want to be interrupted, and for which I
# don't have the source code!
#
# File: y.c
# To build: gcc -o y y.c
#
# #include <stdio.h>
# int main(int argc, char *argv[]) {
# printf("Performing a critical operation...\n");
# for(;;); // Do nothing forever.
# printf("Performing a critical operation... done.\n");
# }
./y
Run Code Online (Sandbox Code Playgroud)
问候,
/ HS
caf*_*caf 13
进程信号掩码是继承的exec,因此您只需编写一个阻塞SIGINT并执行目标的小包装器程序:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGINT);
sigprocmask(SIG_BLOCK, &sigs, 0);
if (argc > 1) {
execvp(argv[1], argv + 1);
perror("execv");
} else {
fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
}
return 1;
}
Run Code Online (Sandbox Code Playgroud)
如果你编译这个程序noint,你只需要执行./noint ./y.
作为注释中的流行音符,信号处理也是继承的,因此您可以让包装器忽略信号而不是阻塞信号:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
struct sigaction sa = { 0 };
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, 0);
if (argc > 1) {
execvp(argv[1], argv + 1);
perror("execv");
} else {
fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
}
return 1;
}
Run Code Online (Sandbox Code Playgroud)
(当然,对于腰带和牙套的方法,你可以做到这两点).