按可执行文件名称搜索进程,排除那些没有 TTY 的进程?

按可执行文件名称搜索进程,排除那些没有 TTY 的进程?

我正在尝试搜索具有给定可执行名称的进程有关联的 TTY。

我的用例是尝试识别正在运行的abduco客户端进程。由于abduco运行带有关联 TTY 的客户端进程和没有关联 TTY 的服务器进程,因此我可以使用它来区分它们。

到目前为止,我已经想出了两种方法。我可以运行:

ps ao pid,comm | grep abduco

默认情况下(不添加选项x)仅考虑具有关联 TTY 的进程。

或者我可以利用ps -C可执行文件名称来选择进程,而不必通过管道来选择grep该部分。但这将包括没有关联 TTY 的进程,并且看起来没有ps提供更改该设置的选项。所以我必须做一些后处理来过滤掉报告 TTY 的进程?

ps -C abduco o pid,tty

有更清洁的解决方案吗?

答案1

请注意,每个系统都有自己的ps命令,每个命令都有自己的语法和功能。

POSIX 确实指定了一个ps命令,尽管许多选项是可选的。

您使用的选项都不是标准的。ps ao是 BSD 风格的语法,ps -C是 HP/UX 选项。您必须使用psprocps 的实现,因为它尝试合并来自许多不同ps实现的功能。

即使有了这个,我也不知道可以告诉它报告具有给定名称和控制 tty 的进程。

所以你需要进行后处理:

ps -o pid= -o tty= -C abduco | awk '$2 != "?" {print $1}'

无论如何,请注意-C "$string"匹配进程名称,而不是真正的可执行文件名称。在 Linux 上,进程名称是一个最多 15 个字节的字符串,是进程的属性。它是从父进程继承的,并且每次进程执行execve()系统调用时都会更改,在这种情况下,进程名称将更改为传递到的文件路径的基本名称的前 15 个字节execve()(因此从这个意义上说,这是一个可执行文件名称),或者通过prctl(PR_SET_NAME)电话(尽管这种情况比较罕见)。

要匹配进程正在运行其代码的可执行文件,您需要查看/proc/<pid>/exe符号链接(在 Linux 上)。

例如,与zsh

print -rC1 -- /proc/*/exe(e['[[ $REPLY -ef =bzip2 ]]']:h:t)

将报告运行该命令的进程的 pid bzip2(在符号链接解析后,其与 a in/proc/pid/exe第一次出现的文件相同)。bzip2$PATH

并限制为带有 tty 的:

() {
  print -rC1 -- /proc/$^@/exe(e['[[ $REPLY -ef =bzip2 ]]']:h:t)
} $(ps ao pid=)

但是,由于bzip2, bunzip2,bzcat都是相同的文件,因此可执行文件的匹配实际上不如进程名称的匹配有用,因为该命令不会区分调用bzip2bunzip2的进程bzcat

aka aka查看其基本名称来决定是否压缩/解压缩/bzcat,因此严格来说bzcat,这应该是我们想要匹配的内容(在Linux 上找到),但这可能不值得付出努力,因为超过 99%当时,它的基本名称与传递给 的可执行文件的基本名称相同(尽管没有被截断)。bzip2bunzip2argv[0]/proc/pid/cmdlineargv[0]execve()

相关内容