我刚刚注意到将前台进程发送到后台并将变量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。127
126
base
signal number
base
如果$?
保存值为 126、127 或在 129..192 范围内的数字,则无法判断这是来自exit()
子级的代码、由信号引起还是由错误引起exec()
。
另请注意,其中的数字$?
部分取决于操作系统,因为只有少数信号授予了标准化数字。SIGTSTP
在未指定数字的信号中,假设其中的数字$?
来自死亡信号,仍然有办法获取信号名称。
检查这个例子:
$ sleep 100^Z
$ echo $?
152
$ kill -l 152
TSTP
kill -l
from 的值适用$?
于任何POSIX
shell,无论当前操作系统上指定信号的值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
。