在Linux下从用户模式应用程序中按进程名称实现筛选的最佳方法是什么?
我知道的所有方法都依赖于阅读proc_fs:
/proc/$PID/exe
/proc/$PID/cmdline
,直到第一个空字符/proc/$PID/status
如果与方法3结合使用,第一种方法似乎是可靠的。不幸的是,(deleted)
当从系统中删除可执行文件时,路径会带有后缀,该后缀可以是普通文件名的后缀部分。如果将此类名称用于可执行文件,则过滤器将不可靠。
第二种方法取决于启动该过程的外壳。这只是该过程的第一个参数(位置0),对于IIUC,shell可以自由地对其进行适当设置。例如,bash将破折号加在登录shell之前。
第三种方法依赖于直接从内核task_struct中的字段获取的,被截断为15个字符的名称。这显然不是很可靠,但它是内核进程可用的唯一名称,因此必须补充其他两个名称。(显然,如果名称包含非ASCII字符,它们将显示为转义序列,因此该方法是可靠的。)
总而言之,我无法提出一种鲁棒的,与Shell无关的方法来支持按进程可执行文件名(或理想的路径)进行过滤,允许使用任意文件名。我可能会使用cmdline中的领先命令参数,因为它可能符合我的目的,但是我想确保自己了解可用的选项。
注意:安全性虽然是一个问题,但却是另一回事。如果需要安全性,将检查该过程的用户身份。但是我希望名称过滤器只是正确性。目的是可靠地实现服务质量或每个进程的配置,并且将涉及进程名称过滤。
/proc/$PID/exe
通过对stat
链接本身和readlink的结果进行一对s可以提高第一种方法(readlink )的鲁棒性。如果您获得匹配的st_dev
和st_ino
,则它们是同一文件。如果没有找到匹配项,或者没有得到ENOENT
,请检查" (deleted)"
字符串的末尾,将其剥离,然后重试。重复直到获得匹配项或" (deleted)"
实例用完。
如果您在所有这些之后都没有找到匹配项,则说明该可执行文件确实已被删除。(在这种情况下,您还没有真正指定要执行的操作,这是您绝对应该考虑的。在坚持健壮性的同时,您不能仅仅忽略删除文件可以使用的事实!)
stat
s之间仍然存在竞争条件,因此您可能想同时打开两个文件和fstat
它们。然后,如果获得设备+节点的匹配,则可以使用一个文件描述符,可以确信它实际上属于目标进程中执行的文件,而不是具有类似名称的其他文件。
下一个困难是,如果过程本身在测试过程中消失了,并且PID被重用了。如果您对此/proc/$PID/stat
有所担心,则可以从操作的开始和结束读取过程的开始时间,以确保整个过程中都在处理相同的过程。(此外,还有一种防止进程消失的方法:使用ptrace作为调试器附加到该进程。)
然后是一个问题,如果您在查看过程时该进程执行了另一个程序,您想做什么。/proc/$PID/exe
将改变。如果您的最终一致性检查后立即发生,你将返回的值是正确的,但现在不是了。除了ptrace之外,您对此无能为力,而且比您想要的更具侵入性。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句