“ps -u”真的是一个糟糕的语法吗?

sjn*_*ngm 76 linux shell ps

恕我直言,ps -u显示了一个非常有用的输出,比ps -u $USER

$ ps -u
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
elastic   234897  0.0  0.0 105980  1336 pts/2    S+   Oct10   0:00 /bin/bash ./run.sh collector-json-1.conf
elastic   234899 48.7  7.1 10087120 4433104 pts/2 Sl+ Oct10 2804:11 /usr/java/jdk1.7.0_09_x64/bin/java -Xmx6144m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -Djava.awt.headless=true -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatin
:
Run Code Online (Sandbox Code Playgroud)

相比

$ ps -u $USER
    PID TTY          TIME CMD
 234897 pts/2    00:00:00 run.sh
 234899 pts/2    1-22:44:04 java
:
Run Code Online (Sandbox Code Playgroud)
  1. 但是,为什么它是“糟糕的语法”?/usr/share/doc/procps-3.2.8/FAQ没有多大帮助。
  2. 实现完全相同的输出的“正确语法”是什么?

如果它很重要:

$ uname -a
Linux h22k34.local 2.6.32-042stab044.17 #1 SMP Fri Jan 13 12:53:58 MSK 2012 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

Joh*_*024 131

返回相同输出的正确语法是:

ps u
Run Code Online (Sandbox Code Playgroud)

现代语法 forps一团糟是有充分理由的。历史上,有两个不兼容的ps. 带前导破折号的选项继承自ps. 没有前导破折号的选项是从 BSD 继承的。psLinux 发行版通常使用的版本是 GNU,它将两组选项合并在一起,并添加了自己的一组以双破折号开头的选项。

因此,ps u是 BSD 风格和ps -u $USERAT&T 风格。事实上,GNUps允许您运行,ps -u并且除了警告之外,还得到与ps uGNU相同的输出,这表明 GNU 正试图在糟糕的情况下做到最好。


use*_*686 85

ps历史上,该命令在 BSD 和 System V Unix 中具有截然不同的语法。

  • BSD 中psu选项(无破折号)不接受任何参数,并显示带有附加列的“面向用户的输出”。

  • SunOS 中ps,该-u选项(带破折号)以用户名作为参数,仅包含该用户拥有的进程,但不更改显示格式。

(作为另一个非常常见的例子,BSD 的e意思是“显示环境”,而 SunOS 的-e意思是“显示每个人的进程”。)

Linux procps ps尝试支持这两种风格。因此,如果您使用 'dash' 选项-u,它将期望它是 SunOS“过滤此用户”选项,而不是扩展列选项。然而,这两者经常混淆,以至于procps 会尝试按照您的意思去做——如果用户名丢失,它会假设您给了它一个 BSD 选项但使用了 SunOS 语法。

(实际上有很多不同的变体psprocps有一个实际的“个性”表来强制将模棱两可的行为解释为一种风格或另一种风格——除了像“UNIX95”、“CMD_ENV”这样的旋钮, "_XPG", "I_WANT_A_BROKEN_PS"...)

  • ……一开始,我还以为是开玩笑呢。[但不...](http://web.archiveorange.com/archive/v/wIO5K6N91IBt8nR8IfqV#ScOH7vyAGrCxCj5) (42认同)
  • “I_WANT_A_BROKEN_PS”哈哈。 (29认同)
  • 嗯,事实证明,这正是隐藏 OP 看到的警告的“歧义用法”的选项。 (9认同)