设置是,我现在在当前目录下有两个文件夹,busybox-1.36.1
和,并且我还有一个正在运行的procps-4.0.4
服务。现在观察不同的行为:languagetool
DynamicUser=yes
图例:✅ 不截断;❌ 截断。
busybox 手表 & busybox ps ✅
./busybox-1.36.1/bin/watch './busybox-1.36.1/bin/ps aux | grep languagetool'
Every 2.0s: ./busybox-1.36.1/bin/ps aux | grep languagetool 2025-03-17 23:20:02
1026972 61534 39:36 java ...languagetool...
4053857 mathiass 0:00 ./busybox-1.36.1/bin/watch ./busybox-1.36.1/bin/ps aux | grep languagetool
4053882 mathiass 0:00 sh -c -- ./busybox-1.36.1/bin/ps aux | grep languagetool
4053884 mathiass 0:00 grep languagetool
busybox 观看并 procps ps ✅
./busybox-1.36.1/bin/watch './procps-4.0.4/bin/ps aux | grep languagetool'
Every 2.0s: ./procps-4.0.4/bin/ps aux | grep languagetool
languag+ 1026972 0.1 13.6 14468788 4464816 ? Ssl Mar04 39:38 java ...languagetool...
mathias+ 4057218 0.0 0.0 4676 2244 pts/32 S+ 23:35 0:00 ./busybox-1.36.1/bin/watch ./procps-4.0.4/bin/ps aux | grep languagetool
mathias+ 4057222 0.0 0.0 231736 3788 pts/32 S+ 23:35 0:00 sh -c -- ./procps-4.0.4/bin/ps aux | grep languagetool
mathias+ 4057224 0.0 0.0 230732 2520 pts/32 S+ 23:35 0:00 grep languagetool
procps 观看 & procps ps ❌
./procps-4.0.4/bin/watch './procps-4.0.4/bin/ps aux | grep languagetool'
Every 2.0s: ./procps-4.0.4/bin/ps aux | grep languagetool
mathias+ 4056463 0.0 0.0 230836 3320 pts/32 S+ 23:31 0:00 ./procps-4.0.4/bin/watch ./procps-4.0.4/bin/ps aux | grep languagetool
mathias+ 4056540 0.0 0.0 230836 1532 pts/32 S+ 23:32 0:00 ./procps-4.0.4/bin/watch ./procps-4.0.4/bin/ps aux | grep languagetool
mathias+ 4056541 0.0 0.0 231736 3556 pts/32 S+ 23:32 0:00 sh -c -- ./procps-4.0.4/bin/ps aux | grep languagetool
mathias+ 4056543 0.0 0.0 230732 2244 pts/32 S+ 23:32 0:00 grep languagetool
procps 监视 & busybox ps ✅
./procps-4.0.4/bin/watch './busybox-1.36.1/bin/ps aux | grep languagetool'
Every 2.0s: ./busybox-1.36.1/bin/ps aux | grep languagetool nixos: Mon Mar 17 23:33:31 2025
1026972 61534 39:38 java ...languagetool...
4056826 mathiass 0:00 ./procps-4.0.4/bin/watch ./busybox-1.36.1/bin/ps aux | grep languagetool
4056831 mathiass 0:00 ./procps-4.0.4/bin/watch ./busybox-1.36.1/bin/ps aux | grep languagetool
4056832 mathiass 0:00 sh -c -- ./busybox-1.36.1/bin/ps aux | grep languagetool
4056834 mathiass 0:00 grep languagetool
问题
奇怪的是,在其他所有情况下,命令的行为都符合我的预期,除了尝试同时使用ps
和watch
from 时procps
。有人知道这是怎么回事吗?
似乎正在发生的行为是procps 手册页 讨论的行为,尽管它不在最明显的地方。在页面的一半或更下方,有一个名为“标准格式说明符”的部分,描述了与选项一起使用的关键字
-o
。该部分以表格形式列出了每个说明符单词、其标题以及它显示的信息的描述。要检查的特定选项是“
args
”。的描述字段args
相当长,但开头说输出是命令和参数。进一步深入描述我们发现:它的意思是 procps 尝试找出它输出到的终端窗口的宽度。无论你是否使用
-o args
,procps 总是会这样做。当它无法找出宽度时 - 通常是因为它的输出没有直接进入终端窗口 - procps 可能会选择你不喜欢的宽度。因此,截断很可能是将输出通过管道传输到命令的副作用
grep
。如上所示,w
向 procps 选项添加如下内容:可能会解决这个问题,或者通过
COLUMNS
将变量设置为更大的值来调用它,如下所示:可能会更好。
通常,当输出没有到达终端时,
procps
'ps
不会截断命令行,但除非$COLUMNS
设置了环境变量,并且procps
的实现watch
确实根据它所运行的终端的宽度来设置它¹。但是在这里,您不需要运行(这里使用实际上被 busybox 忽略的
ps | grep
非标准API ),而只需执行以下操作:ps aux
ps
(或者
watch -x pgrep -af languagetool
使用 procps'watch
来避免不必要的 shell 调用)。pgrep
,将仅与完整-f
“进程参数列表”匹配正则表达式,而不会报告其自身或其祖先(例如此处的命令)。watch
请注意,虽然
busybox
确实有一个pgrep
小程序,但它并不总是启用的。这里,为了仅在命令行上匹配而不包括
sh
、grep
/awk
和watch
在 procps 和 busybox 实现之间可移植的命令ps
,您可以执行以下操作:¹ ksh、zsh、bash 或 fish 等 Shell 也设置了
$COLUMNS
Shell变量(在 bash 的情况下,非交互时则不然),但默认不会将其导出到环境中。² 或者尽可能多地获取,因为早期版本的 Linux 内核仅提供了前 4096 个字节。
³ 与空格连接,并对一些字符(如控制字符)进行转换,类似于
ps -wwo args
。