获取有关短期进程的信息

获取有关短期进程的信息

我想跟踪现有进程,尤其是它们的参数(如环境变量、cwd 目录、stdout 等)。我能做到。但是,我无法获得有关短期进程的信息)。例如:

如果我运行:

sleep 120 & 
# get info from /proc/`pgrep sleep` 

这很容易。

但是,如果我的进程立即终止或者我不知道进程的 PID(但我预计会创建一些进程)怎么办?

答案1

作为普通用户的一种方法是exec包装器,假设程序是通过PATH搜索运行的。也就是说,你的包装program

#!/bin/sh
env > /some/log/file
... (any other desired logging commands here) ...
exec /path/to/real/program "$@"

必须首先存在于 中PATH,因此您可能有PATH=/some/wrapper/dir:$PATH一个完全为要记录的program真实名称命名的包装器,并且在包装器中您可以使用原始包装器替换包装器。如果程序通过完全限定的路径运行,那么可能需要摆弄类似的东西,或者相关应用程序可能会提供更改路径的选项?programprogramprogramexecLD_PRELOAD

因为root使用类似sysdig(各种 sysdig 示例)因为它可以匹配您感兴趣的临时进程名称,并且可以逐步深入到您感兴趣的内容,假设程序ls以某个用户身份运行:

sudo sysdig "proc.name = ls and user.name = jhqdoe" | tee log

运行log后相当冗长的文件显示一个条目,该条目可能提供您所需的几乎所有内容(环境被截断):lsexecve

9734 16:12:49.683389228 1 ls (20542) < execve res=0 exe=ls args=--color=auto. tid=20542(ls) pid=20542(ls) ptid=20052(bash) cwd= fdlimit=1024 pgft_maj=0 pgft_min=61 vm_size=404 vm_rss=4 vm_swap=0 comm=ls cgroups=cpuset=/.cpu_cgroup=/.cpuacct=/.mem_cgroup=/.devices=/user.slice.freezer=/.ne... env=XDG_SESSION_ID...

通过用户指南和其他文档,上述内容可以精确到仅调用execve和显示的完整环境:

sudo sysdig -p "%proc.env" "proc.name = ls and user.name = jhqdoe and evt.type = execve" | tee xxx

调整-p以显示您想要的内容;您还可以使用凿子从实时捕获或保存文件等中提取您想要的内容。

答案2

你必须使用forkstat(1)或其他一些使用的程序过程连接器界面。不幸的是,您只能以 root 身份执行此操作。另外,它不可扩展或可编写脚本,因此如果您还希望它打印进程的环境、其控制 tty 等,forkstat(1)您可能必须编写自己的程序,将 proc 连接器中的数据与 from 中的数据结合起来。procfs

这是一种非常粗略的“扩展”方法,forkstat(1)可以打印二进制文件的实际路径和进程的当前目录execve

stdbuf -o0 forkstat -e fork,exec | perl -anle '
  print;
  if($F[1] eq "exec"){
     print "\texe = ", readlink "/proc/$F[2]/exe";
     print "\tcwd = ", readlink "/proc/$F[2]/cwd";
  }
' 

作为普通用户,您唯一的解决方案是运行父进程,通过以下方式启动这些短期进程(或其祖先之一):

strace -s1024 -vfe trace=execve prog args ...

-s选项控制将打印多少 argv 和 env 字符串strace。通过运行程序strace可能会对性能产生相当大的影响。可能还有其他更友好/可编写脚本的替代方案,但如果普通用户要使用它们,则strace(1)它们都必须使用,因此不要期望它们有本质上的不同。ptrace(2)

相关内容