如何中断不可中断的程序?

如何中断不可中断的程序?

如果我mysqld从命令行运行,它会显示一些启动消息,然后停止响应。它不产生输出,并且忽略任何输入,而且似乎没有办法摆脱它。 ctrl+z 和 ctrl+c 不执行任何操作,无法返回终端 - 我必须开始一个新会话。这意味着,例如,如果我通过 ssh 连接到服务器,我必须启动一个新的 ssh 连接。

这很烦人。 bash 有什么方法可以告诉它停用当前正在运行的进程吗?我可以使用 ctrl+z 暂停任何其他程序,但不能使用 mysqld,尽管我不知道为什么。如果我启动它,mysqld &那么它会在后台运行,只要我不错误输入fg,我就可以正常向它发送信号,否则它的行为就像一个普通进程,所以我不知道为什么 ctrl +z 对它没有影响,因为我认为这是 bash 的一部分,而不是在进程的控制之下。

那么:当 ctrl+z 不起作用时,是否有替代 ctrl+z 的方法?

答案1

该命令stty -a将显示当前终端中的所有键盘快捷键。一般来说,在类 Unix 系统中,唯一映射的信号是Ctrl+ C(SIGINT)、Ctrl+ \(SIGQUIT) 和Ctrl+ Z(SIGTSTP)。没有与其他信号的其他绑定,因此您无法在当前会话中使用键盘发送其他信号。

一般来说,d程序名称的最后一个通常表示“守护进程”。守护进程旨在在后台运行,并通过标准输入/输出之外的其他方式进行操作(如管道、信号、套接字...)。这意味着它可能当程序本身没有在后台运行时,您会得到意外的行为(例如终端似乎“挂起”,因为守护进程对输入、输出做了一些事情,或者它正在循环中做一些事情/等待)

通常,守护进程也可能具有针对特定信号的陷阱并以不同的方式处理它们(甚至忽略它们)。您是否尝试过在后台运行时发送 SIGINT ( kill -2,相当于Ctrl+ C)、SIGQUIT ( kill -3,相当于Ctrl+ \) 或 SIGTSTP ( kill -20,相当于Ctrl+ Z) mysqld,只是为了测试目的?

编辑:要更改stty映射,您需要编写:

stty <action> <new-mapping>

例如,将 SIGINT 重新映射到Ctrl+X

stty intr ^x

请注意,此设置仅在当前会话期间在当前终端中有效。

答案2

Ctrl+Z实际上是内核中通用终端接口的一个功能,而不是 bash 的功能。它会导致 SIGTSTP 信号发送到前台进程。同样,Ctrl+C发送 SIGTERM,Ctrl+\发送 SIGQUIT。

程序可以通过两种方式导致Ctrl+Z失去其效果。

  • 程序可以忽略 SIGTSTP 信号。
    您可以使用调试器检查进程的信号行为。在 Linux 上,可以通过以下方式获取该信息/procgrep Sig /proc/1234/status其中 1234 是进程 ID,显示哪些信号被忽略(SigIgn,它们只会无害地反弹)或被阻止(SigBlk,它们被置于等待状态,直到程序允许它们进入)。该数字是位掩码并以十六进制写出。 SIGTSTP 是信号 20(kill -l在 bash 中运行),因此如果该SigIgn行右侧第五位数字为 8 或以上,则该信号将被忽略。
  • 该程序可以更改键绑定。
    您可以使用命令行检查当前的键绑定,例如运行进程的终端在stty -a </dev/pts/42哪里。/dev/pts/42寻找susp = ^Z

守护进程可能会忽略大多数信号。如果它本身不分叉,则在后台启动它(大多数守护进程实际上在启动后立即分叉子进程并立即让父进程分叉)。如果您在前台启动它,有很多方法可以恢复(向它或其父 shell 发送信号),但您需要另一个 shell。

相关内容