为什么使用bash并暂停while循环,然后在恢复循环后停止循环?下面的简短示例。
$ while true; do echo .; sleep 1; done
.
.
^Z
[1]+ Stopped sleep 1
$ fg
sleep 1
$
我熟悉信号,我猜这可能是bash的自然行为,但我想更好地理解为什么它会以这种特定方式运行。
为什么使用bash并暂停while循环,然后在恢复循环后停止循环?下面的简短示例。
$ while true; do echo .; sleep 1; done
.
.
^Z
[1]+ Stopped sleep 1
$ fg
sleep 1
$
我熟悉信号,我猜这可能是bash的自然行为,但我想更好地理解为什么它会以这种特定方式运行。
Answers:
这看起来像是几个shell中的错误,可以按预期与ksh93和zsh一起工作。
背景:
大多数shell似乎在主shell内运行while循环,
如果您使用非登录外壳输入^ Z,则Bourne Shell会挂起整个外壳
bash仅挂起the sleep
,然后离开while循环,以便打印新的shell提示符
破折号使该命令不可悬浮
使用ksh93,事情就大不相同了:
在第一次启动命令时,ksh93会执行相同的操作,但与sleep
ksh93中的buitin一样,ksh93具有一个处理程序,该处理程序会导致while循环派生出主外壳,然后在您键入^ Z时挂起。
如果您稍后在ksh93中键入fg
,则继续运行循环的派生子节点将继续。
比较bash和ksh93的jobcontrol消息时,您会看到主要区别:
bash报告:
[1]+ Stopped sleep 1
但ksh93报告:
^Z[1] + Stopped while true; do echo .; sleep 1; done
zsh的行为类似于ksh93
对于这两个Shell,只要不键入^ Z,您就有一个进程(主shell),而在键入^ Z之后,您将拥有两个shell进程。
dash
循环终止时,实际上没有处理信号吗?在[d]?ash
源代码中,所有用于INTON和INTOFF的宏都散布在各处,通常在INTOFF状态下接收到的信号实际上是在INTON处(或周围) 处理的。无论如何,我只是很好奇,因为我想您知道得更多-这是一个很好的答案。谢谢。
sleep 100
可以在中暂停和恢复单个文件dash
,因此似乎dash
了解此命令中的问题并有选择地禁用作业控制。
dash
通过删除多字节处理,您是否能够在其他shell中实现与性能相同的性能?是的,dash
它确实支持作业控制,但是该标准说交互式外壳程序应该忽略TSTP,并且在交互式终端上的当前外壳程序中运行while循环与其他外壳程序一样,都是交互式外壳程序。
关于这个问题,我写了一位Bash的合著者,这是他的回复:
这不是一个真正的错误,但肯定是一个警告。
这里的想法是暂停进程,该进程与Shell命令的粒度单位不同。当进程被挂起时,它返回到外壳程序(状态为非零,当您停止一个作为循环测试的进程时会产生后果),它可以选择:它可以中断或继续循环,留下已停止的过程。当工作停止时,Bash选择-一直选择-跳出循环。继续循环很少是您想要的。
其他一些Shell会执行一些操作,例如,当某个进程由于SIGTSTP而被挂起时,派生该Shell的副本,并停止该进程。Bash从未做到过-似乎比收益保证书还复杂-但如果有人想以补丁形式提交该代码,我将考虑合并这些更改。
因此,如果有人想提交补丁,请使用手册页中找到的电子邮件地址。
$?
在返回时准确地反映出来,所以true
不是true
。大概。我认为。