除了“CPU 的 MMU 发送信号”和“内核将其定向到违规程序并终止它”之外,我似乎找不到任何关于此的信息。
我认为它可能将信号发送到外壳,外壳通过终止违规进程和打印来处理它"Segmentation fault"。所以我通过编写一个我称之为crsh(废话 shell)的极简 shell 来测试这个假设。除了获取用户输入并将其提供给system()方法之外,此外壳不执行任何操作。
#include <stdio.h>
#include <stdlib.h>
int main(){
char cmdbuf[1000];
while (1){
printf("Crap Shell> ");
fgets(cmdbuf, 1000, stdin);
system(cmdbuf);
}
}
Run Code Online (Sandbox Code Playgroud)
所以我在一个裸终端中bash运行了这个 shell(没有在下面运行)。然后我继续运行一个产生段错误的程序。如果我的假设是正确的,这将 a) 崩溃crsh,关闭 xterm,b) 不打印"Segmentation fault",或 c) 两者兼而有之。
braden@system ~/code/crsh/ $ xterm -e ./crsh
Crap Shell> ./segfault
Segmentation fault
Crap Shell> [still running]
Run Code Online (Sandbox Code Playgroud)
回到第一个,我猜。我刚刚证明了不是外壳执行此操作,而是下面的系统。“分段错误”是如何打印出来的?“谁”在做?内核?还有什么?信号及其所有副作用如何从硬件传播到程序的最终终止?
我有一个 Bash 脚本,它看起来类似于:
#!/bin/bash
echo "Doing some initial work....";
/bin/start/main/server --nodaemon
Run Code Online (Sandbox Code Playgroud)
现在,如果运行脚本的 bash shell 收到一个 SIGTERM 信号,它也应该向正在运行的服务器发送一个 SIGTERM(它会阻塞,所以不可能有陷阱)。那可能吗?
如何验证正在运行的进程是否会捕获信号、忽略它或阻止它?理想情况下,我希望查看信号列表,或者至少不必实际发送信号进行检查。
对于许多例子trap使用trap ... INT TERM EXIT的清理任务。但是真的有必要列出所有三个 sigspecs 吗?
手册上说:
如果 SIGNAL_SPEC 为 EXIT (0),则在退出 shell 时执行 ARG。
我相信这适用于脚本是否正常完成或因为它收到SIGINT或SIGTERM. 一个实验也证实了我的信念:
$ cat ./trap-exit
#!/bin/bash
trap 'echo TRAP' EXIT
sleep 3
$ ./trap-exit & sleep 1; kill -INT %1
[1] 759
TRAP
[1]+ Interrupt ./trap-exit
$ ./trap-exit & sleep 1; kill -TERM %1
[1] 773
TRAP
[1]+ Terminated ./trap-exit
Run Code Online (Sandbox Code Playgroud)
那为什么这么多例子一一列举INT TERM EXIT呢?或者我错过了什么,有没有鞋底EXIT会错过的情况?
给定一个 shell 进程(例如sh)及其子进程(例如cat),如何使用 shell 的进程 ID模拟Ctrl+的行为C?
这是我尝试过的:
运行sh然后cat:
[user@host ~]$ sh
sh-4.3$ cat
test
test
Run Code Online (Sandbox Code Playgroud)
发送SIGINT到cat从另一终端:
[user@host ~]$ kill -SIGINT $PID_OF_CAT
Run Code Online (Sandbox Code Playgroud)
cat 收到信号并终止(如预期)。
向父进程发送信号似乎不起作用。为什么信号cat在发送到其父进程时没有传播到sh?
这不起作用:
[user@host ~]$ kill -SIGINT $PID_OF_SH
Run Code Online (Sandbox Code Playgroud) 当一个进程被一个可处理的信号杀死时,例如SIGINTorSIGTERM但它不处理该信号,该进程的退出代码是什么?
对于无法处理的信号,例如SIGKILL?
据我所知,杀死进程SIGINT可能会导致退出代码130,但这会因内核或外壳实现而异吗?
$ cat myScript
#!/bin/bash
sleep 5
$ ./myScript
<ctrl-c here>
$ echo $?
130
Run Code Online (Sandbox Code Playgroud)
我不确定如何测试其他信号...
$ ./myScript &
$ killall myScript
$ echo $?
0 # duh, that's the exit code of killall
$ killall -9 myScript
$ echo $?
0 # same problem
Run Code Online (Sandbox Code Playgroud) 我熟悉几个过程信号以及它们的作用,但我想了解它们。
关于每个信号,我想了解三件事。
这是信号列表和我目前所拥有的。
0 - ?
1 - SIGHUP - ?, controlling terminal closed,
2 - SIGINT - interupt process stream, ctrl-C
3 - SIGQUIT - like ctrl-C but with a core dump, interuption by error in code, ctl-/
4 - SIGILL
5 - SIGTRAP
6 - SIGABRT
7 - SIGBUS
8 - SIGFPE
9 - SIGKILL - terminate immediately/hard kill, use when 15 doesn't work or when something disasterous might happen if process is allowed to …Run Code Online (Sandbox Code Playgroud) 我有一个命令,每次它终止时我都想自动再次运行,所以我运行了这样的命令:
while [ 1 ]; do COMMAND; done;
Run Code Online (Sandbox Code Playgroud)
但如果我不能停止循环,Ctrl-c因为那只会杀死COMMAND而不是整个循环。
我将如何实现类似的功能,但无需关闭终端即可停止?