如何确定进程是否正在运行并使用它来制作条件shell脚本?

Nir*_*mik 132 bash process

如何确定进程是否正在运行,然后让 bash 脚本根据该条件执行一些内容?

例如:

  • 如果进程abc正在运行,请执行此操作

  • 如果它没有运行,请执行此操作。

Joh*_*nac 200

执行类似操作的 bash 脚本如下所示:

#!/bin/bash

# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern. 

if pgrep -x "gedit" > /dev/null
then
    echo "Running"
else
    echo "Stopped"
fi
Run Code Online (Sandbox Code Playgroud)

这个脚本只是检查程序“gedit”是否正在运行。

或者您只能检查程序是否没有像这样运行:

if ! pgrep -x "gedit" > /dev/null
then
    echo "Stopped"
fi
Run Code Online (Sandbox Code Playgroud)

  • @Silviu 嗯?谷歌搜索`/dev/null`:“/dev/null 将命令标准输出重定向到空设备,这是一种丢弃写入其中的信息的特殊设备”......使用`0` 会将命令输出重定向到名为“0”的文件。在这种情况下,我建议对 `> /dev/null` 更加适应——你会在任何地方看到它,因为它是丢弃输出的标准/正确方法。 (3认同)
  • 请将 `-x` 参数添加到 `pgrep` 中,以便它查找确切的应用程序,否则如果在另一个应用程序的名称中找到相同的字符串,它将得到错误正确的结果。我只花了 1 小时才找到答案。 (3认同)

gei*_*rha 37

任何使用类似ps aux | grep abcpgrep abc有缺陷的解决方案。

为什么?

因为您没有检查特定进程是否正在运行,所以您正在检查是否有任何正在运行的进程恰好匹配abc. 任何用户都可以轻松创建和运行名为abc(或abc在其名称或参数中包含某处)的可执行文件,从而导致测试误报。有可应用于各种选项psgreppgrep以缩小搜索范围,但你仍然不会得到一个可靠的测试。

那么如何可靠地测试某个正在运行的进程呢?

这取决于您需要测试的目的。

我想确保服务abc正在运行,如果没有,请启动它

这就是 systemd 的用途。它可以自动启动服务并跟踪它,它可以在它死亡时做出反应。

请参阅如何检查我的游戏服务器是否仍在运行...以获取其他解决方案。

abc是我的脚本。我需要确保我的脚本只有一个实例正在运行。

在这种情况下,请使用锁定文件或锁定目录。例如

#!/usr/bin/env bash

if ! mkdir /tmp/abc.lock; then
    printf "Failed to acquire lock.\n" >&2
    exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT  # remove the lockdir on exit

# rest of script ...
Run Code Online (Sandbox Code Playgroud)

有关其他锁定方式,请参阅Bash FAQ 45

  • 虽然这在技术上是正确的,但我个人在现实生活中从未遇到过这样的问题。大多数程序不会以破坏脚本的方式更改它们的名称。因此,对于简单的脚本,诸如 `pgrep` 或 `ps` 之类的东西就完全足够了,而你的方法似乎有点矫枉过正。但是,如果您正在编写用于公开分发的脚本,则应该以最安全的方式编写它。 (5认同)
  • 我说错了。但是我们中的许多人运行单用户系统。在多用户情况下,也很容易 grep 用户名。 (3认同)
  • @ScottSeverance Programs 更改名称不是问题;无论如何,这都需要干预。是其他用户运行相同的程序,或其他具有相似名称的程序会突然导致脚本误报,从而做错事。我只是更喜欢“作品”而不是“大部分作品”。 (2认同)
  • @jp093121 脚本退出时触发 EXIT 陷阱。无论它是因为到达脚本结尾、退出命令还是接收到信号(可以处理)而退出,都会运行 `rm` 命令。所以只要它在陷阱设置后结束,锁就应该消失。 (2认同)

Zuu*_*uul 20

这是我使用的:

#!/bin/bash

#check if abc is running
if pgrep abc >/dev/null 2>&1
  then
     # abc is running
  else
     # abc is not running
fi
Run Code Online (Sandbox Code Playgroud)

通俗地说如果 'pgrep' 返回 0,则进程正在运行,否则不运行。


相关阅读:

Bash 脚本 ::字符串比较

Ubuntu 手册pgrep


小智 6

我通常pidof -x $(basename $0)在我的脚本上有一个来检查它是否已经在运行。