Pie*_*pin 4 less terminal signals git mercurial
我偶尔会使用镐功能来git
定位感兴趣的更改。显然,这可能非常慢(这同样适用于,比如说hg grep
),但更重要的是它是突发的:一些结果聚集在一起,由不活动分开。
出于这些原因,我尝试在结果出现时读取结果,实际上通过将输出管道传输到less
(事实上,这是git
默认情况下的操作):当突发到来时,您不可能ctrl-S
对软件流程足够快地击中控制功能现在很有用。
但我经常遇到一个\xe2\x80\xa6 行为,less
如果我滚动得足够多,即使只有一行要在屏幕上显示的内容还没有从命令中出来git
,less
就会陷入困境,并且我会失去它的提示和大多数方式控制它,直到更多内容出现。现在,我明白为什么会发生这种情况,但如果这是 shell 命令的行为,我会使用ctrl-Z
恢复提示(然后执行bg
)。是否有等效的方法less
来恢复寻呼机提示?
在这种情况下,ctrl-Z
没有用:Unix 作业控制不适合管理屏幕内容的命令。此外,我不想回到 shell 提示符:通常,我想做的是检查我在反复按空格键时可能瞥见的内容,所以我不想留下更少的内容。
Ctrl-C
也是无用的:虽然它确实允许我恢复提示,但这还会导致收到的内容被冻结;也就是说,当我的好奇心得到满足并尝试返回到最新内容(按几下空格键或G
等)时,无论我等多久,都只会出现我所看到的内容。即使使用F
(tail -f
模式)。
我使用此命令来模拟git
行为:
(echo -e 'foo\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.' ; sleep 3 ; echo -e 'bar\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.' ; sleep 10; echo baz) | less\n
Run Code Online (Sandbox Code Playgroud)\n
事实上,解决方案是使用ctrl-C
,但同时确保生成的信号不会发送到通过管道传输到 的其他命令less
。这是我最初未能获得的决定性见解:虽然仅从less
终端执行读取,因此普通输入仅适用于该命令,但另一方面,源自终端驱动程序的信号被分派到管道中的所有进程。
以这种方式控制信号调度说起来容易做起来难。据我所知,没有好的解决方案,因此我提出了最不坏的解决方案:用于setsid(1)
将其他命令隔离到它们自己的会话中:
% setsid sh -c "/bin/echo -e 'foo\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.' ; sleep 3 ; /bin/echo -e 'bar\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.' ; sleep 10; /bin/echo baz" sh-c | less
Run Code Online (Sandbox Code Playgroud)
通过此设置,当我点击时,ctrl-C
我得到了预期的行为:less
提示出现在它之前可以收到的内容之后,sleep
我可以浏览回之前的所有内容,当我直接返回到最新内容时,最后一个内容( baz
,此处) 最终出现。通过将内容生成填充到其自己的会话中,我将该进程与信号隔离(我需要涉及该信号以中断读取操作,否则该读取操作将less
被卡住)。
主要问题是这setsid(1)
完全不标准;虽然所有 Unix 和类 Unix 内核都支持setsid(2)
系统调用,但它作为独立命令的可用性有点像 Linux 主义。如果它在您的安装中不可用,您最喜欢的包管理器应该提供它(源很简单并且位于公共领域),无论是单独提供还是作为包的一部分util-linux
:
% brew install util-linux # MacOS
Run Code Online (Sandbox Code Playgroud)
不要被这个名字误导:setsid(1)
至少,它是可移植的。(注意:util-linux
此处显示的 Homebrew 的 cask 仅包含 keg,即由于冲突,搜索路径中未安装任何内容;您必须手动将其 bin 目录添加到$PATH
)