为什么我无法将 pgrep 输出正确地分配给 bash 脚本上的变量?

为什么我无法将 pgrep 输出正确地分配给 bash 脚本上的变量?

我正在尝试制作一个脚本,以便在 compton 正在运行时退出它,或者在它未运行时启动它。我从 man 那里读到,如果找到进程,它应该退出 1,所以我尝试制作一个使用它的脚本...但是这不起作用,如果它关闭,它就会启动,但不会关闭它。我究竟做错了什么 ??

#!/bin/bash


status=$(pgrep compton 2>&1)

if [[ $status == 1 ]];
    then
        killall compton
    else
        exec compton -b
fi

echo $status

答案1

获取变量pgrep中的输出status。这只是不是您期望的输出。

pgrep输出与您给定的模式匹配的进程的进程 ID (PID)。如果存在名称与 匹配的进程compton,则将$status是该进程或这些进程的 PID。 pgrep还返回退出状态,但命令替换不会将退出状态捕获为字符串。

在您的测试中,您将$status与进行比较1。 PID不太可能为compton1。


如果您想终止任何compton存在的进程,并compton -b在不存在进程时启动compton,您可以使用

#!/bin/sh

if ! pkill compton; then
    exec compton -b
fi

这使用 的退出状态pkill。该pkill工具的工作方式与pgrep(它们通常作为一对进行分发和安装)相同,但不是像pgrep以前那样输出匹配进程的 PID,而是将信号(默认情况下)pkill发送TERM到匹配进程。

if关键字使用与其一起使用的命令的退出状态。

颠倒!了测试的意义,使得

  • 如果pkill compton成功,就说明有曾是一个或多个compton进程现在已被终止,或至少已发出信号,并且exec compton -b不会被执行。

  • 如果pkill compton失败(没有进程与名称匹配,或者 中存在一些内部错误pkill),语句的主体if将调用您的exec compton -b,这将用运行 产生的进程替换 shell 进程compton -b

答案2

您应该控制 pgrep 进程的退出状态,该状态将在 $?多变的。或者检查存储 pgrep 输出的 $status 变量是否是非零长度字符串。问题中的脚本检查变量状态中的字符串是否为“1”

所以

#!/bin/bash
pgrep compton >/dev/null

if [[ $? -eq 0 ]]
then
    killall compton
else
    exec compton -b
fi

或者

#!/bin/bash
status=$(pgrep compton 2>&1)

if [[ -n "$status" ]]
then
    killall compton
else
    exec compton -b
fi

相关内容