Linux:如何知道进程在哪里启动以及它是如何启动的?

Fer*_*ndo 48 linux

我正在检查一个 Linux 框,发现一个 perl 进程正在运行并占用了大量的 cpu 使用率。使用 top,我只能在进程名称中使用 perl。

当我按c查看命令行时,它显示 /var/spool/mail。这是没有意义的,因为这是目录。

我的问题是:

1)为什么会这样?这个 perl 进程如何掩盖它的命令行?2) 找出流程开始的位置和方式的最可靠方法是什么?

谢谢!

cor*_*ump 70

最可靠的方法是查看/proc进程的目录。每个进程都有一个/proc/<pid>/目录,其中保存如下信息:

  1. cwd 链接到当前工作目录
  2. fd 带有指向打开文件(文件描述符)链接的目录
  3. cmdline 阅读它以查看用于启动进程的命令行
  4. environ 该进程的环境变量
  5. root 指向进程认为它是根目录的链接(它将是 / 除非被 chroot)

每个进程/proc 都有更多很酷的信息,但是通过上面的信息,您将能够确切地知道发生了什么。

此外,使用ps auxf将向您显示谁分叉了什么,以便您可以更好地了解谁在调用您的 perl。

  • 我总是在 Windows 上使用 Process Explorer,并且想知道 Linux 上是否有等效的工具。那个开关就可以完成一切!ps auxf ...不错! (3认同)
  • +1 为 ps 的 f 参数,它为我做到了! (3认同)
  • +1 教我什么似乎是这样一个基本概念...`/proc` 包含进程信息!谁知道??我在那里寻找的只是`version`和`cpuinfo`之类的东西......加上这解决了我的实际问题,因为我的路由器版本的ps忽略了所有参数 (2认同)

lar*_*sks 41

在大多数情况下,只需运行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
Run Code Online (Sandbox Code Playgroud)

需要注意的是,可见的信息ps可以被正在运行的程序完全覆盖。例如,这段代码:

int main (int argc, char **argv) {
        memset(argv[0], ' ', strlen(argv[0]));
        strcpy(argv[0], "foobar");
        sleep(30);
        return(0);
}
Run Code Online (Sandbox Code Playgroud)

如果我将它编译成一个名为“myprogram”的文件并运行它:

$ gcc -o myprogram myprogram.c
$ ./myprogram &
[1] 10201
Run Code Online (Sandbox Code Playgroud)

然后运行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
Run Code Online (Sandbox Code Playgroud)

您也可以直接查看/proc/<pid>/exe,它可能是指向相应可执行文件的符号链接。在上面的示例中,这为您提供了比ps以下更有用的信息:

$ls -l /proc/9600/exe
lrwxrwxrwx. 1 lars lars 0 Feb  8 11:31 /proc/9600/exe -> /usr/bin/lftp
Run Code Online (Sandbox Code Playgroud)

  • 总而言之,`/proc` 中的文件将提供有关程序的所有信息,`exe` 将是指向可执行文件的链接,`cwd` 指向当前工作目录,`fd` 目录包含指向打开文件的链接(包括标准输入、输出和标准错误) (3认同)

inf*_*era 20

对我来说,刚才,我发现它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} ]
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以使用:

systemctl status <PID>
Run Code Online (Sandbox Code Playgroud)

或使用进程名称:

systemctl status $(pgrep perl)
Run Code Online (Sandbox Code Playgroud)

这将提供有关启动您的流程的 systemd 服务的信息。

我在这里找到了这个提示