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

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

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

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

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

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

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

这只会生成所需的grep进程。这个技巧是使用[]字符类(正则表达式)。通常在字符组中只放入一个字符是毫无意义的,因为[c]总是匹配到“c”。在这种情况下,也是一样的。grep [n]ame搜索“name”。但由于grep自己的进程列表条目是你所执行的命令(“grep [n]ame”),而不是“grep name”,所以它不会匹配到自身。
守护进程管理
上述所有的内容在你处于交互式shell提示符时都是可以的,但不应该在脚本中使用。这太不可靠了。
大多数时候,当有人问类似的问题时,是因为他们想使用原始的shell脚本技术来管理一个长时间运行的守护进程。常见的变体是“我如何获取我的foobard进程的PID……以便在它尚未运行时启动一个”或“我如何获取我的foobard进程的PID……因为我想要阻止foobard脚本在foobard已经运行时运行”。这两个问题都会导致严重缺陷的生产系统。
如果你真正想要的是在守护进程停止时重新启动它,只需要这样做:

其中--in-the-foreground是任何必须提供给守护进程的选项,用于阻止它自动转入后台运行。 (通常,-d可以实现这一点,并且还具有以增加的详细程度运行守护进程的附加好处。)
如果这样做太简单了,可以尝试使用daemontools或runit,这些是用于管理服务的程序。
如果你真正想要的是防止多个实例的程序同时运行,那么确保做到这一点的唯一可靠方法是使用锁。
了解更多shell技巧可以进入我的专栏了解更多
专栏里包含一线大厂工作多年涉及的必备的shell核心知识点,可以帮你快速了解shell技巧,了解shell必备技能,提升工作效率。