为什么将进程发送到后台设置$?为非零值?

为什么将进程发送到后台设置$?为非零值?

我刚刚注意到将前台进程发送到后台并将变量Ctrl-Z设置$?为非零值。为什么会这样呢?

这种行为让我很困扰,因为我想要一个终端提示符,当命令错误时它会改变颜色,我做了以下操作这个答案。然而,这也意味着,如果我在 Vim 中工作,每次我将其发送到后台时,Ctrl-Z提示都会改变颜色,就好像出了问题一样。

答案1

(假设bash

Ctrl-Z 不会将进程发送到后台(本来bg %JOB_NUMBER),它暂停它。为此,将向进程发送 SIGSTP 信号(您可以使用 自己执行此操作kill -SIGSTP PID)。 SIGSTP 是信号 20。

你看到的返回值是148 或 128 + SIGSTP

因此,您应该更改该答案中的代码来检查该条件,它始终是 148。

答案2

您所看到的问题是由使用古董引起的,$?该古董无法区分程序死亡的原因,从而丢失信息。

$?如果无法找到程序,如果可以找到文件但无法执行文件,则包含exit()程序代码的低 8 位;如果程序被信号终止,则包含+ 。是一个取决于 shell 的数字,通常为 128、256 或 512。127126basesignal numberbase

如果$?保存值为 126、127 或在 129..192 范围内的数字,则无法判断这是来自exit()子级的代码、由信号引起还是由错误引起exec()

另请注意,其中的数字$?部分取决于操作系统,因为只有少数信号授予了标准化数字。SIGTSTP在未指定数字的信号中,假设其中的数字$?来自死亡信号,仍然有办法获取信号名称。

检查这个例子:

$ sleep 100^Z
$ echo $?
152
$ kill -l 152
TSTP

kill -lfrom 的值适用$?于任何POSIXshell,无论当前操作系统上指定信号的值base和信号编号如何。

如果您使用的是用户友好的 shell(例如bosh),则不止$?.看这个例子:

$ sleep 100^Z
$ echo ${.sh.codename} ${.sh.termsig} ${.sh.status} $/ $?
KILLED TSTP 24 TSTP 152
$ (exit 1234567890)
$ echo ${.sh.codename} ${.sh.termsig} ${.sh.status} $/ $?
EXITED UNKNOWN 1234567890 1234567890 210

${.sh.codename}是列表中儿童死亡原因的名称EXITED KILLED DUMPED TRAPPED STOPPED CONTINUED NOEXEC NOTFOUND

${.sh.termsig}是与状态码相关的信号名称

${.sh.status}是数字状态代码。

上述三个变量是bosh具体的。

$/是当前POSIX$?后继程序的建议,其中包含程序正常退出时的数字以及信号 或NOEXEC或 的文本NOTFOUND

我的示例使用exit()仅适用于POSIX兼容操作系统的 32 位代码。该值210是表达式 的结果1234567890 & 0xFF

相关内容