0

在我的操作系统上,默认情况下,ZSH 有-tostop(或者是 tty?)。

这允许后台进程在有输出时输出到 shell。

因此:

> stty -tostop
> echo 'random' >/tmp/random
> cat /tmp/random &
[1] 7588
random
[1]  + 7588 done       cat /tmp/random

相应地:

> stty tostop
> echo 'random' >/tmp/random
> cat /tmp/random &
[1] 3888
[1]  + 3888 suspended (tty output)  cat /tmp/random

阅读文档并进行一些实验,我发现 ZSH 有 4 种类型的挂起进程(您可以使用 来查看kill -$SIGNAL $PID ; jobs):

job state              - signal that gives you job state
suspended              - SIGTSTP
suspended (signal)     - SIGSTOP
suspended (tty input)  - SIGTTIN
suspended (tty output) - SIGTTOU

这将意味着3888进程正在接收 SIGTTOU 信号。

这一切都说得通。

现在我的问题是,为什么它less不受stty tostopor影响stty -tostop

> stty tostop
> less /tmp/random &
[1] 6300
[1]  + 6300 suspended (tty output)  less --LONG-PROMPT --chop-long-lines /tmp/random

> stty -tostop
> less /tmp/random &
[1] 4808
[1]  + 4808 suspended (tty output)  less --LONG-PROMPT --chop-long-lines /tmp/random

正如您在这两种情况下看到的那样,less总是在后台暂停。

现在,我知道了less -X,而且我也知道了终端仿真器具有的备用屏幕功能。实际上,您可以使用 运行上述 2 个命令less -X,它会导致相同的暂停。即使-X使它不使用备用屏幕,仍然少suspended (tty output)

我想知道的是如何less始终暂停的实际机制suspended (tty output),即使在tostop切换时,甚至在-X切换时也是如此。除非有其他方式被暂停,否则shell 怎么能一直发送SIGTTOU到。lessless

4

1 回答 1

1

(你没有指定你的操作系统,但这个答案是基于 linux 的)

使用strace您可以看到在 termios 结构的值中stty执行ioctlon fd 0 (stdin) 切换一位。c_lflag

strace还透露less将打开/dev/tty并发布一个ioctl关于它的更改c_lflag

因此,只需在输出任何内容之前less执行相同的操作即可。stty tostop

于 2016-04-23T19:13:59.957 回答