如何通过进程id查找文件所在位置 (如何根据进程id获取进程网络)

如何通过进程名称查找进程的进程ID?

通常情况下,我们会使用进程ID(PID)来引用一个进程,并且ps(1)命令可以根据进程ID显示任何进程的信息,例如:

通过进程名查进程号,通过进程路径取进程id

但是经常情况下,我们只知道进程的名称而不知道其进程ID。一些操作系统,例如Solaris、BSD和某些版本的Linux,提供了专用的命令来根据进程名称搜索进程,称为pgrep(1):

通过进程名查进程号,通过进程路径取进程id

通常还有更专门的程序可用,不仅可以根据进程名称查找进程的进程ID,还可以向其发送信号:

通过进程名查进程号,通过进程路径取进程id

有些系统还提供了pidof(1)​命令。它与pgrep​的区别在于,输出的多个进程ID之间只用空格分隔,而不是换行分隔。

通过进程名查进程号,通过进程路径取进程id

如果这些程序不可用,用户可以使用ps​命令的输出进行grep​搜索。

在使用grep​搜索ps​输出时的一个主要问题是,grep​可能匹配到自身的ps​条目(尝试运行:ps aux | grep init​)。更糟糕的是,这种情况并非每次都发生;技术上称之为竞争条件。为了避免这种情况,有几种方法:

  • 在末尾使用grep -v​

通过进程名查进程号,通过进程路径取进程id

将从输出中删除所有包含“grep”的行。缺点是你始终有grep -v​的退出状态,所以你不能检查特定进程是否存在。

  • 在中间使用grep -v​

通过进程名查进程号,通过进程路径取进程id

这和上面的方法完全相同,只是“grep name”的退出状态是可访问的,可以表示“name是ps​中的一个进程”或“name不是ps​中的一个进程”。它仍然有一个缺点,即启动一个新进程(grep -v​)。

  • 在grep​中使用[]​

通过进程名查进程号,通过进程路径取进程id

这只会生成所需的grep​进程。这个技巧是使用[]​字符类(正则表达式)。通常在字符组中只放入一个字符是毫无意义的,因为[c]​总是匹配到“c”。在这种情况下,也是一样的。grep [n]ame​搜索“name”。但由于grep​自己的进程列表条目是你所执行的命令(“grep [n]ame”),而不是“grep name”,所以它不会匹配到自身。

守护进程管理

上述所有的内容在你处于交互式shell提示符时都是可以的,但不应该在脚本中使用。这太不可靠了。

大多数时候,当有人问类似的问题时,是因为他们想使用原始的shell脚本技术来管理一个长时间运行的守护进程。常见的变体是“我如何获取我的foobard进程的PID……以便在它尚未运行时启动一个”或“我如何获取我的foobard进程的PID……因为我想要阻止foobard脚本在foobard已经运行时运行”。这两个问题都会导致严重缺陷的生产系统。

如果你真正想要的是在守护进程停止时重新启动它,只需要这样做:

通过进程名查进程号,通过进程路径取进程id

其中--in-the-foreground​是任何必须提供给守护进程的选项,用于阻止它自动转入后台运行。 (通常,-d​可以实现这一点,并且还具有以增加的详细程度运行守护进程的附加好处。)

如果这样做太简单了,可以尝试使用daemontools或runit,这些是用于管理服务的程序。

如果你真正想要的是防止多个实例的程序同时运行,那么确保做到这一点的唯一可靠方法是使用锁。

了解更多shell技巧可以进入我的专栏了解更多

专栏里包含一线大厂工作多年涉及的必备的shell核心知识点,可以帮你快速了解shell技巧,了解shell必备技能,提升工作效率。