我正在尝试搜索具有给定可执行名称的进程和有关联的 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 选项。您必须使用ps
procps 的实现,因为它尝试合并来自许多不同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
都是相同的文件,因此可执行文件的匹配实际上不如进程名称的匹配有用,因为该命令不会区分调用bzip2
或bunzip2
的进程bzcat
。
aka aka查看其基本名称来决定是否压缩/解压缩/bzcat,因此严格来说bzcat
,这应该是我们想要匹配的内容(在Linux 上找到),但这可能不值得付出努力,因为超过 99%当时,它的基本名称与传递给 的可执行文件的基本名称相同(尽管没有被截断)。bzip2
bunzip2
argv[0]
/proc/pid/cmdline
argv[0]
execve()