Coreutils timeout(1) 与 man/less 配合不好

Coreutils timeout(1) 与 man/less 配合不好

我想less(1)在我们公司的生产服务器上为命令设置超时。我们每天都会在其上生成大型日志文件,尽管每晚都有批处理作业来归档/删除它们,但有时我们会收到磁盘使用率过高的警报,因为(长时间)运行的进程可能会阻止文件unlink(2)因引用而物理地被 -ed - POSIX 文件系统的语义计数。

为了避免此类烦恼的最常见情况,我编写了一个包装器,在less其下运​​行它timeout(1)以便空闲less进程在几个小时后自动终止,而不在文件系统中保留打开的文件。

但结果却表现得很糟糕:当命令通过环境变量man(1)启动包装器时,它停止响应任何键盘输入。这是一个最小的可重现测试用例:manPAGER

$ PAGER='timeout 12h /bin/less' man man

运行后,ps fx输出如下所示:

19415 pts/1    SNs    0:00  \_ -bash
19854 pts/1    SN+    0:00      \_ man man
19867 pts/1    SN     0:00          \_ timeout 12h /bin/less
19869 pts/1    TN     0:00              \_ /bin/less

我只能kill -KILL 19869重新获得对终端的访问权限。

我在这里做错了什么?为什么less进程处于T状态,而不是S

答案1

回答我自己的问题,因为我无法通过谷歌搜索真正找到任何提示。

strace(1)实际上可以显示SIGTTOU已发送到less进程的信息。

这与 类似SIGTTIN,但当后台作业中的进程尝试写入终端或设置其模式时生成。 ...剪断...

显然timeout(1)默认情况下将管理下的进程置于后台:

--foreground

不要创建单独的后台程序组,以便托管命令可以正常使用前台TTY。 ...剪断...

所以我的问题的解决方案是

$ PAGER='/bin/timeout --foreground 12h /bin/less' man man

(以及我的包装中的等效内容)

相关内容