我检查了一台 Linux 机器,发现一个正在运行的 perl 进程占用了大量 CPU 使用率。使用 top,我只能在进程名中看到 perl。
当我按下C,查看命令行,它显示 /var/spool/mail。这没有意义,因为这是目录。
我的问题是:
1) 为什么会发生这种情况?这个 perl 进程如何掩盖其命令行?2) 找出进程启动位置和启动方式的最可靠方法是什么?
谢谢!
答案1
在大多数情况下,只需运行ps
通常就足够了,同时使用您喜欢的标志来启用宽输出。我倾向于ps -feww
,但这里的其他建议也有效。请注意,如果某个程序是从某人的 启动的$PATH
,您只会看到可执行文件名称,而不是完整路径。例如,试试这个:
$ lftp &
$ ps -feww | grep ftp
lars 9600 9504 0 11:30 pts/10 00:00:00 lftp
lars 9620 9504 0 11:31 pts/10 00:00:00 grep ftp
需要注意的是,可见的信息ps
可能会被正在运行的程序完全覆盖。例如,以下代码:
int main (int argc, char **argv) {
memset(argv[0], ' ', strlen(argv[0]));
strcpy(argv[0], "foobar");
sleep(30);
return(0);
}
如果我将其编译成名为“myprogram”的文件并运行它:
$ gcc -o myprogram myprogram.c
$ ./myprogram &
[1] 10201
然后运行ps
,我会看到一个不同的进程名称:
$ ps -f -p 10201
UID PID PPID C STIME TTY TIME CMD
lars 10201 9734 0 11:37 pts/10 00:00:00 foobar
您也可以直接查看/proc/<pid>/exe
,它可能是指向相应可执行文件的符号链接。在上面的示例中,它比 提供了更多有用的信息ps
:
$ls -l /proc/9600/exe
lrwxrwxrwx. 1 lars lars 0 Feb 8 11:31 /proc/9600/exe -> /usr/bin/lftp
答案2
最可靠的方法是查看/proc
进程的目录。每个进程都有一个/proc/<pid>/
目录,用于保存以下信息:
cwd
链接到当前工作目录fd
包含打开文件(文件描述符)链接的目录cmdline
阅读它以查看使用什么命令行来启动进程environ
该进程的环境变量root
指向进程认为是其根目录的链接(除非经过 chrooted,否则它将是 /)
每个进程 /proc 上还有更多有趣的信息,但通过以上信息,您将能够确切地知道发生了什么。
此外,使用ps auxf
将显示谁分叉了什么,以便您更好地了解谁在调用您的 perl。
答案3
对我来说,刚才我发现这pstree
比ps aux
它看起来像这样:
├─lightdm─┬─Xorg
│ ├─lightdm─┬─init─┬─apache2───2*[apache2───26*[{apache2}]]
│ │ │ ├─at-spi-bus-laun─┬─dbus-daemon
│ │ │ │ └─3*[{at-spi-bus-laun}]
│ │ │ ├─at-spi2-registr───{at-spi2-registr}
│ │ │ ├─dbus-daemon
│ │ │ ├─dropbox───29*[{dropbox} ]
答案4
尝试ps axww | grep perl
获取进程的完整命令行。它看起来top
只是修剪了一条长线。