ps -e 将进程名转换为小写

ps -e 将进程名转换为小写

ps -e将大写进程名称转换为小写。我无法在手册页或在线中找到对该行为的解释,并且我不擅长阅读源代码来从中找出答案。

我通常使用ps -ef(完整格式列表),因此从未注意到这种行为,但 DBA 注意到了。

-e小写是流程线的预期行为吗?有人能解释为什么它被编码为小写吗?

这是相同过程的示例,但使用-e和 then with -ef

server ~> ps -e | grep -Ei pmon
2187719 ?        00:00:02 ora_pmon_foobar
2188497 ?        00:00:02 ora_pmon_phuuba
2188928 ?        00:00:02 ora_pmon_kilgor
[printed as lowercase when instance name (end of line) should be uppercase ]

server ~> ps -ef | grep -Ei pmon
oracle   2187719       1  0 04:00 ?        00:00:02 ora_pmon_FOOBAR
oracle   2188497       1  0 04:00 ?        00:00:02 ora_pmon_PHUUBAR
oracle   2188928       1  0 04:01 ?        00:00:02 ora_pmon_KILGORE
[prints upper case, which is good]

-ealone 也会截断,但这就是我们得到-f.主要对-e小写进程感到好奇。

答案1

ps有和没有-f在列中给出不同的信息CMD

在 Linux 上,

  • 没有-f,这就是进程名称。进程的属性,长度限制为 15 个字节。该属性由系统调用(用于执行命令)设置execve()为正在执行的文件的基本名称,截断为 15 个字节,也可以由进程使用prctl(PR_SET_NAME).与返回的结果相同ps -o comm。它可以在/proc/pid/stat内部(...)或现场Name:看到/proc/pid/status
  • 与-f,这就是参数列表用空格字符连接。这些是argv[0]在第二个参数中传递给execve()已执行命令的进程(或其任何祖先)的系统调用的参数(包括)。 arg 列表可以在 中看到 NUL 分隔/proc/pid/cmdline。与返回的结果相同ps -o args。它曾经被截断为 4096 字节,但在最近版本的 Linux 中不再如此(尽管ps除非给定选项,否则会截断它本身以进行输出-w)。进程可以(有限制地)通过在找到该信息的堆栈部分写入新文本来更改这一点。

/proc/pid/exe也将是进程当前正在运行的可执行文件的符号链接(如 所报告的ps -o exe),这也可能不同。

无论如何,除了转义不可打印的字符之外,ps不会对这些字符进行任何转换。

你可以运行:

ps -wwo comm,args,exe -p 2187719

要查看 id 2187719 进程的进程名称、参数列表和可执行文件。您可以使用ps以下命令检查获取该信息的原始源:

cat /proc/2187719/stat
sed -n l /proc/2187719/cmdline
readlink /proc/2187719/exe

例子:

$ cp /usr/bin/sleep 'A longer sleep command for demonstration'
$ (exec -a 'SLEEP though could be anything' './A longer sleep command for demonstration' Infinity) &
[1] 6723
$ ps -fp "$!"
UID          PID    PPID  C STIME TTY          TIME CMD
chazelas    6723    6668  0 06:17 pts/2    00:00:00 SLEEP though could be anything Infinity
$ ps -p "$!"
    PID TTY          TIME CMD
   6723 pts/2    00:00:00 A longer sleep
$ cat "/proc/$!/stat"
6723 (A longer sleep ) S 6668 6723 6668 34818 6726 4194304 154 0 0 0 0 0 0 0 25 5 1 0 17863 19312640 448 18446744073709551615 94858855174144 94858855192393 140731919224688 0 0 0 0 0 0 1 0 0 17 0 0 0 0 0 0 94858855206160 94858855207424 94858855886848 140731919232547 140731919232587 140731919232587 140731919237069 0
$ sed -n /Name/l "/proc/$!/status"
Name:\tA longer sleep $
$ sed -n l "/proc/$!/cmdline"
SLEEP though could be anything\000Infinity\000$
$ perl -e '$0 = "whatever you want"; sleep 20' &
[1] 13861
$ ps -wo comm,args,exe -p "$!"
COMMAND         COMMAND                     EXE
whatever you wa whatever you want           /usr/bin/perl

就您而言,如果情况有所不同,可能是因为

  • 这些过程做了execve("/path/to/ora_pmon_foobar", ["ora_pmon_FOOBAR", NULL], envlist);
  • 他们做到了execve("/path/to/anything", ["ora_pmon_FOOBAR", NULL], envlist)anything也可能是ora_pmon_FOOBAR),但后来做了一个prctl(PR_SET_NAME, "ora_pmon_foobar")
  • 他们这样做了execve("/path/to/ora_pmon_foobar", ["ora_pmon_foobar", NULL], envlist);,但后来用 覆盖了argv[0]它们ora_pmon_FOOBAR

或者以上的组合。例如,在 中perl,分配 to 会$0同时更改进程名称和参数列表,如上例所示。


1 除非该参数列表为空,例如execve()由进程以空列表作为第二个参数调用时(导致argc== 0),或者它们或其任何祖先都没有execve()像内核任务那样调用过的进程。在这种情况下,ps -f会在方括号内显示进程/任务名称。

相关内容