关于备用屏幕和后台暂停的使用,启动 less 与在 ZSH 中启动 cat 有何不同
How does launching `less` differ from launching `cat` in ZSH with regards to the usage of alternate screen and background suspension
在我的 OS 上,默认情况下,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 tostop
或 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
,而且我还知道终端仿真器具有的备用屏幕功能。 事实上,您可以 运行 使用 less -X
执行上述 2 个命令,它会导致相同类型的暂停。 即使 -X
成功了不使用备用屏幕,less 仍然得到 suspended (tty output)
!
我想知道 less
总是被 suspended (tty output)
暂停的实际机制,即使 tostop
被切换,甚至 -X
也正在切换。 shell 怎么可能总是将 SIGTTOU
发送到 less
,除非有其他方式 less
被暂停。
(你没有指定你的 OS,但这个答案是基于 linux)
使用 strace
你可以看到 stty
在 fd 0 (stdin) 上执行 ioctl
切换 termios 结构的 c_lflag
值中的一位。
strace
还显示 less
将打开 /dev/tty
并在其上发出 ioctl
以更改 c_lflag
.
所以 less
在输出任何内容之前简单地做与 stty tostop
相同的事情。
在我的 OS 上,默认情况下,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 tostop
或 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
,而且我还知道终端仿真器具有的备用屏幕功能。 事实上,您可以 运行 使用 less -X
执行上述 2 个命令,它会导致相同类型的暂停。 即使 -X
成功了不使用备用屏幕,less 仍然得到 suspended (tty output)
!
我想知道 less
总是被 suspended (tty output)
暂停的实际机制,即使 tostop
被切换,甚至 -X
也正在切换。 shell 怎么可能总是将 SIGTTOU
发送到 less
,除非有其他方式 less
被暂停。
(你没有指定你的 OS,但这个答案是基于 linux)
使用 strace
你可以看到 stty
在 fd 0 (stdin) 上执行 ioctl
切换 termios 结构的 c_lflag
值中的一位。
strace
还显示 less
将打开 /dev/tty
并在其上发出 ioctl
以更改 c_lflag
.
所以 less
在输出任何内容之前简单地做与 stty tostop
相同的事情。