在Unix中结束进程而不是中断它


12

Unix命令行中,如果按Ctrl-C,则该操作不会结束进程,而是会中断进程,然后返回到shell提示符。

因此,我有以下两个问题:

    1. 有没有办法查看所有中断进程的列表并结束它们?
    1. 按什么组合键可以结束一个过程而不是中断它?

Answers:



7

从历史上看,有三个信号绑定到击键,这些是

  • SIGINT(中断)通常Ctrl+ CDel
  • SIGQUIT-退出-通常绑定到Ctrl+\
  • SIGSUSP挂起-通常绑定到Ctrl+Z

在某些* nix风格上,还绑定了其他信号,您可以使用以下命令检查键盘绑定

stty -a

在我的系统OS / X上,这将产生以下输出

speed 9600 baud; 65 rows; 213 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

请注意,在这种情况下,kill并非KILL信号,而是与清除当前输入缓冲区有关。

使用SIGQUIT停止进程可能会取得更大的成功,但这可能不是正确的,因为进程可能会捕获信号并忽略它。

没有“已中断”进程列表的概念,因为该进程已捕获并忽略了该中断或已退出。您可以通过输入作业来获取挂起进程的列表


有趣的是,我显示了^ Q和^ S(就像您一样),但是设置stty -ixon了它们以便通过。我认为他们会变成<undef>
暂停,直到另行通知。

我的OS X框或Debian Lenny框的手册页中都找不到SIGSUSP。好像是SIGTSTP。
dmckee ---前主持人小猫,2010年

DEL-

5

许多正确答案,但没有一个是完整的。

  1. 正如许多其他人所说:Control-C通常发送Unix信号SIGINT,默认行为(来自不覆盖它的程序)是“终止进程”。程序可以忽略该信号,也可以根据需要采取其他措施。
  2. 您也可以使用Control- \从键盘发送SIGQUIT。此处的区别在于,默认情况下,该进程将写入一个核心文件,然后退出。程序可以忽略该信号,也可以根据需要采取其他措施。
  3. 要以极端的偏见终止而不允许进程停止,请使用SIGKILL,它默认情况下不与任何键绑定。相反,您通常使用kill (1)命令发送它,并指定要发送的信号

    $ kill -9 <process ID>
    

    或助记符

    $ kill -KILL <process ID>
    

    该信号由操作系统直接处理,程序无法覆盖默认行为。

  4. 如果您的Shell支持作业控制,则它可能还支持其内置版本,kill该版本支持使用Catwalk的answer中%字符进行作业识别。

  5. 要以可恢复的方式暂停进程,请使用Control-z,它发送SIGTSTP。您可以fg通过继续控制终端或bg保持终端控制的情况下使它继续运行来恢复这样的过程(但是,默认情况下,仍将其输出发送到那里)。

另外,在SIGQUIT上转储核心取决于许多管理细节。ulimit -c,Solaris上的coreadm(1M)等。另一个注意事项-fg发送SIGCONT信号,使进程恢复其操作。
Tadeusz A.Kadłubowski10年

1
  1. 查看后台进程列表: jobs

    杀死:(kill %1jobs输出中对应的作业ID替换1 )

  2. 这里

1

Ctrl-C发送SIGINT,默认情况下会导致进程结束,但可以将其捕获(\bin sh使用,在中trap)。

SIGKILL是不可陷阱的杀死信号。

编辑第三次,我认为这是正确的:我已经根据文档检查了所有内容。走着瞧。


SIGKILL不可捕获。

是的 我已经解决了这个问题
查尔斯·斯图尔特

1

对于大多数终端新手来说,这还不是很清楚,但是如果您的问题只是您在一个交互式程序中,而您又不知道该如何退出,那么很多时候q就会退出。例如,这是退出的关键less,它也是查看man页面时获得的程序等。

某些程序还有其他键盘快捷键可以退出。在vimvi中使用ESC:wq。在emacs,使用Control-C Control-X。在nanopico中使用Control-X。请注意,在这些示例中,存在一些细微之处,特别是关于这些快捷方式是否保存了您可能正在编辑的文件所做的任何更改。


那么什么是标准?
Pacerier '17

0

许多进程可以安装中断处理程序来捕获中断信号,但是默认情况下不会中断的那些处理程序。

要强制退出进程,可以发送SIGQUIT(Ctrl- \)。


SIGQUIT可以被困,SIGKILL不能被困。
查尔斯·斯图尔特

1
@Charles:另一个区别是SIGQUIT默认情况下会转储核心,而SIGKILL不会。
Tadeusz A.Kadłubowski10年

0

似乎其他答案是可能的情况,但您执行的脚本也可能无法正确处理其子级。我最近遇到了类似的情况,即杀死一个脚本不会杀死该脚本的子进程。

通常,如果遇到这种情况,则必须检查所有正在运行的进程。您应该查看ps的联机帮助页。(man ps)我特别喜欢使用ps auxwf,它显示了进程之间的父/子关系。pstree做类似的事情。您应该终止进程之前从另一个终端运行此命令,以查看正常情况下的情况并确定子进程。

如果然后(用^ C杀死)该主进程,请再次检查ps的输出以查看是否有任何更改。如果子进程仍然存在,则可以使用kill命令将其杀死。(请参阅man kill

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.