如何使用标准实用程序在 bash 中解锁信号?
在过去的几周里,我注意到 Macos 上的 shell 挂起(例如,yes | head
不终止)。深入研究后发现,我创建的所有新 shell 都阻止了相当大的信号集。 (因此,在前面的示例中,yes
正在阻止 SIGPIPE。工具编写者的警示;检查 、 等的返回值write
)printf
。
这种行为有点烦人,但现在我知道了问题所在,解决起来很容易。但还不够容易。 trap
似乎没有达到目的(我正在使用 bash)。我可以向我的 bash 启动添加什么来使用标准实用程序清除一组被阻止的信号?我添加了以下内容,感觉非常混乱:
if { ! show-mask && which unblock; } > /dev/null 2>&1; then
exec unblock bash
fi
其中 show-mask 和 unblock 是从以下版本构建的:
$ cat show-mask.c
/* Show the current set of blocked signals */
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
int
main(int argc, char **argv)
{
struct sigaction act = {{0}};
sigset_t old;
if(sigprocmask(SIG_SETMASK, NULL, &old)) {
perror("sigprocmask");
return EXIT_FAILURE;
}
printf("mask: %x\n", old);
return !!old;
}
$ cat unblock.c
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void
set_default(struct sigaction *act, int s)
{
if(sigaction(s, act, NULL)) {
perror("sigaction");
exit(EXIT_FAILURE);
}
}
int
main(int argc, char **argv)
{
struct sigaction act = {{0}};
sigset_t new;
sigemptyset(&new);
if(sigprocmask(SIG_SETMASK, &new, NULL)) {
perror("sigprocmask");
return EXIT_FAILURE;
}
act.sa_handler = SIG_DFL;
set_default(&act, SIGPIPE);
set_default(&act, SIGINT);
set_default(&act, SIGTERM);
execvp(argv[1], argv+1);
perror("execlp");
return EXIT_FAILURE;
}