为什么 ps 的以下两个命令给出不同的CMD
字段?这很重要,因为screen
和SCREEN
是不同的:第一个是客户端,第二个是服务器。谢谢。
$ ps -A | grep -i screen
3341 ? 00:00:00 screen
3875 ? 00:00:00 screen
27525 ? 00:00:00 screen
$ ps -Af | grep -i screen
testme 3341 1 0 2018 ? 00:00:00 SCREEN -S testme
testme 3875 1 0 2018 ? 00:00:00 SCREEN -S tm
t 27525 1 0 2018 ? 00:00:00 SCREEN -S test
SCREEN
不是一个程序,那为什么它会显示在ps
?
$ SCREEN
SCREEN: command not found
答案1
screen
重命名其主(服务器)进程SCREEN
以将其与后来的客户端区分开来。
在手册页中曾经非常间接地提到过这一点:
请注意,此命令仅影响主“SCREEN”进程的正确调试输出。附加程序进程的调试输出只能永久关闭一次。
但奇怪的是,在我能看到的任何地方都没有明确提及。
ps
并ps -f
为 CMD 显示不同的内容:可执行文件名称(ps
“command”格式说明符)和重建的命令行(ps -f
“args”格式说明符)。后者使用进程的 ARGV 并看到它的更改,而可执行文件名称本身未更改。
答案2
他们不。
严格来说是一个问题为什么他们所做的事情是无法回答的,它以谎言为前提。
他们显示了cmd
和ucmd
列,两个不同的信息片段。不幸的是,GNUps
程序和 FreeBSDps
程序都让事情变得非常混乱。
/proc
Linux 等内核和 BSD 内核通过和中的文件提供有关进程的四个(相关)信息sysctl()
:
- 它的程序映像简称,又名用于流程记账的简称;
- 它的参数字符串,由
execve()
运行时初始化并可修改; - 它的环境字符串,由
execve()
运行时初始化并可修改;和 - 其可执行程序映像文件的完整路径名。
参数字符串和环境字符串可以在运行时按照我介绍的方式进行修改https://unix.stackexchange.com/a/438007/5132和https://unix.stackexchange.com/a/432681/5132。 Linux 还允许修改进程记帐名称。
GNU Screen 修改了其参数字符串,因此第一个参数字符串为“SCREEN”,但不是其进程记帐名称,仍为“screen”。
中只有两列用于显示这四条信息ps
。在 FreeBSD 中ps
,列包含以下信息:
command
由和命名的列args
包含参数字符串,加上环境字符串(如果e
使用该选项),加上方括号中的会计名称(如果与第一个参数字符串不匹配);如果d
使用该选项并且它是最后一列,则全部以树形图为前缀。- 由进程记帐名称命名
ucomm
并包含该列。comm
GNU为前者ps
添加了别名,为后者添加了别名。它将树图和环境字符串放入cmd
ucmd
两个都列,并且始终将树形图放入其中,即使该列是不是最后一栏。
对于 GNU ps
,问题中的-f
选项(不要与选项混淆f
)只是指定要打印的-Af
不同列集的简写。ps
默认的列集包括ucmd
.-f
使用该选项时使用的集合包括cmd
替代。
BSD 手册明确地阐述了这一点,给出了通过其、、和简写ps
选择的确切列。 GNU 手册提到了“完整格式”、“作业格式”、“长格式”和“用户格式”,但没有明确列出每个格式是哪一组列。-j
-l
-u
-v
ps
更令人困惑的是,GNUps
和 FreeBSDps
在其输出中给出的列标题中都不使用命令行上使用的列名称。因此,人们通常无法仅从列标题判断实际显示的是哪一列。
- FreeBSD
ps
将记帐名称列标记为 或UCOMM
,COMMAND
而且还标记参数字符串列COMMAND
。 - GNU
ps
将参数字符串列标记为 或CMD
,COMMAND
而且还将会计名称列标记为CMD
或COMMAND
。
s6-ps
(作为比较,Laurent Bercot 的仅有comm
、args
、 和env
,具有固定且不同的标头标签COMM
、COMMAND
、 和ENVIRONMENT
,直接给出来自内核的四条信息中的前三条,而不将它们组合起来。)
- 洛朗·贝尔科特 (2014)。
s6-ps
。s6-linux-utils。软件。