有一些 Linux 程序,例如 vlc,如果程序在第一个之后没有停止,则建议键入ctrl+c两次以从终端终止它们的执行。
为什么在第一次不起作用时键入ctrl+c两次会起作用?
kill -l在 linux 上执行给出:
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) …Run Code Online (Sandbox Code Playgroud) 我在 C fork() 的子进程中编写了我编写的程序。两个进程都不会终止。如果我从命令行启动程序并按 control-c 哪个进程将收到中断信号?
如果我使用trap如在http://linuxcommand.org/wss0160.php#trap上描述的那样在退出之前捕获 ctrl-c(或类似的)和清理,那么我正在更改返回的退出代码。
现在这可能不会在现实世界中产生影响(例如,因为退出代码不可移植,而且在进程终止时的默认退出代码中讨论的那样并不总是明确的?)但我仍然想知道是否有真的没有办法阻止这种情况并返回中断脚本的默认错误代码吗?
示例(在 bash 中,但不应将我的问题视为特定于 bash 的问题):
#!/bin/bash
trap 'echo EXIT;' EXIT
read -p 'If you ctrl-c me now my return code will be the default for SIGTERM. ' _
trap 'echo SIGINT; exit 1;' INT
read -p 'If you ctrl-c me now my return code will be 1. ' _
Run Code Online (Sandbox Code Playgroud)
输出:
$ ./test.sh # doing ctrl-c for 1st read
If you ctrl-c me now my return code will be the …Run Code Online (Sandbox Code Playgroud) [编辑:这看起来类似于其他一些询问如何杀死所有产生的进程的问题——答案似乎都是使用 pkill。所以我的问题的核心可能是:有没有办法将 Ctrl-C/Z 传播到脚本产生的所有进程?]
当rec使用timeout来自 coreutils的命令(在此处讨论)调用 SoX 时,一旦从 Bash 脚本中调用它,似乎没有任何方法可以通过击键杀死它。
例子:
timeout 10 rec test.wav
Run Code Online (Sandbox Code Playgroud)
...可以用Ctrl+C或Ctrl+Z从 bash杀死,但不能从脚本内部调用它。
timeout 10 ping nowhere
Run Code Online (Sandbox Code Playgroud)
...可以被杀死Ctrl+C或Ctrl+Z从庆典,并与Ctrl+Z当它在脚本中运行。
我可以找到进程 ID 并以这种方式杀死它,但为什么我不能使用标准的中断键击?有什么方法可以构建我的脚本以便我可以吗?
我想在 Linux 机器上的 bash 中同时运行两个命令。因此,在我的./execute.shbash 脚本中,我输入了:
command 1 & command 2
echo "done"
Run Code Online (Sandbox Code Playgroud)
但是,当我想停止 bash 脚本并点击Ctrl+ 时C,只停止第二个命令。第一个命令继续运行。如何确保停止完整的 bash 脚本?或者无论如何,我如何停止这两个命令?因为在这种情况下,无论我按Ctrl+多少次C,命令都会继续运行,我不得不关闭终端。
至少在GNU bash 版本 4.3.42 x86_64 && GNU bash 版本 4.3.11 x86_64 上发生
我使用sleep & wait $!而不是简单的sleep来获得sleep信号的可中断性(如SIGUSR1)。但是wait当您运行以下命令时,bash-builtin 的行为似乎很奇怪。
cat <(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
Run Code Online (Sandbox Code Playgroud)
kill -10 /the pid of the subshell, printed by the previous command/
Run Code Online (Sandbox Code Playgroud)
^C (ctrl + C)
Run Code Online (Sandbox Code Playgroud)
然后,我得到了以 100% 消耗 CPU 的子外壳。
pkill -P $(pgrep -P $$)
Run Code Online (Sandbox Code Playgroud)
你知道为什么会发生这种行为吗?
注意 …
我目前对终端键盘信号的理解是(主要基于尝试将我的观察映射到可以在谷歌上找到的内容)如下:
在此之后它开始变得非常模糊,因为配置什么输入意味着在终端(stty)中完成什么信号。我想这意味着终端本身正在向进程发送信号。但我也认为该终端不知道正在读取它的应用程序。
在终端中通过键盘发送信号如何从头到尾工作?
在他的关于网页的自管绝招,丹·伯恩斯坦解释了竞争条件select()和信号,提供一个解决办法,并得出结论认为,
当然,正确的做法是
fork()返回文件描述符,而不是进程 ID。
他的意思是什么 - 是否能够select()在子进程上处理其状态更改,而不必使用信号处理程序来获取这些状态更改的通知?