运行进程。为什么显示的是UID号码而不是用户名?

25

ps -eaf

..

kude     22593 12078  0 09:06 ?        00:00:02 smbd -D
hasi     22929 12078  0 09:12 ?        00:00:00 someprog.pl
root     22950    43  0 Sep08 ?        00:00:19 [nfsiod]
root     24558    43  0 Sep09 ?        00:00:28 [pdflush]
root     25320     1  0 00:00 ?        00:00:01 /usr/bin/atop -a -w /var/log/atop/atop_20110916 600
1466     25757 12078  0 10:12 ?        00:00:00 smbd -D
root     26752 12078  0 10:32 ?        00:00:01 smbd -D

..

id username2

uid=1466(username2) gid=513(DomainUsers) groups=513(DomainUsers)

所有LDAP用户都被正确配置在/etc/nsswitch.conf中,但只有这个用户没有显示。为什么会显示uid号码(1466)而不是用户名?


1
也许是因为UID号码具有相对可预测的最大长度,而用户名可以非常长? - Eric J.
10
是的,这是用户名的长度(如果超过8个字符,则ps aux将用uid替换名称)。现在运行man ps以获取详细信息。 - Ray Toal
4个回答

38

ps -ef(POSIX)或ps aux(BSD衍生版)中,用户名列表的长度限制为8个字符。选项说明

我在Mac和Linux上搜索了手册页,但没有看到记录该限制的地方。

这个问题经常出现在论坛上,8个字符的限制是答案。

最终,我偶然发现了此页面,其中“错误”报告针对Debian,但被关闭为不是错误。他们引用了此页面,该页面还声称当名称太长时,POSIX和UNIX标准要求回退到uid。也不是来自实际的POSIX标准。

我不知道这是否具有权威性,但它确实解释了您在9个字符的用户名中看到的行为。 :)

也许其他人可以发布更权威链接的答案?


ps aux 是正常的 BSD 语法。你列出的 BSD 实际上是旧的 SysV 语法。 - tchrist
倒霉,反了。谢谢@pst。已修复。 - Ray Toal

11
如Ray Toal所提到的,它受到了8个字符限制。这不是一个错误,而是如Ray所述的标准的一部分。如果您检查procps包中的ps源代码,其中一个注释说:
The Open Group Base Specifications Issue 6 (IEEE Std 1003.1, 2004 Edition)  
requires that user and group names print as decimal numbers if there is
not enough room in the column, so tough luck if you don't like it.

The UNIX and POSIX way to change column width is to rename it:
  ps -o pid,user=CumbersomeUserNames -o comm
The easy way is to directly specify the desired width:
  ps -o pid,user:19,comm

如果您查看“STDOUT”部分中的链接,它会说如果可以获得字段(userrusergrouprgroup"),并且字段宽度允许,那么这些字段将被打印出来;否则将以十进制表示。
用户和组名字段宽度限制为8的原因可能是为了向后兼容,但这只是一个猜想。

3

ps -eo user:$(cut -d: -f1 /etc/passwd | wc -L),pid,ppid,c,stime,tname,time,cmd

这里的-o选项用于指定ps命令的自定义输出格式。

所指定的用户定义格式为输出用户、pid、ppid、stime、tname、time和cmd字段。

cut -d:-f1 /etc/passwd | wc -L 确定密码文件中最长登录名的字符数。因此,user:$(cut -d:-f1 /etc/passwd | wc -L) 让 ps 命令输出使用最长登录名的最大长度的用户字段。


你能否添加一些关于该命令正在执行的附加信息? - dmportella

0

如果你需要更加动态的输出长度,可以使用比moosaka的答案更好的方法(例如,如果你有一些非常长的用户名,但是很少使用,并且你不想浪费屏幕大部分时间),你可以使用以下命令:

ps -eo user:$(ps axho uid | sort -u | xargs getent passwd | cut -f1 -d: | wc -L),pid,ppid,c,stime,tname,time,cmd

它将使得当前运行进程中最长的用户名列的长度与之相同。(请注意,这并不是绝对可靠的,如果在命令运行时出现了一个更长的用户名的新进程,你可能仍然会看到一个数字显示。但是99.99%的时间它都会产生更好的输出效果)

解释:$(ps axho uid [...] | wc -L) 计算当前正在运行的进程的最大用户名长度,然后我们使用该长度执行普通的 ps 命令。

或者,如果你希望 ps 看起来像通常的短用户名(<=8个字符),并且不介意输出中的一些长用户名与标题不对齐,你可以尝试以下命令:

ps ax -o user:40,pid,ppid,c,stime,tname,time,cmd | perl -pe 'if (/^(\S+)/ and length $1 > 8) {s/^(\S+)\s+/$1 /} else { s/^(.{9})\s+/$1/}'
这个命令的作用是让输出的用户名列变得很长(-o user:40),然后对输出进行后处理,使得长用户名(length $1 > 8)只有一个空格与下一列之间,而短用户名(else {)则被修剪回默认值(最多8个字符的用户名,其余部分为第9个字符的空格)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接