![为什么我无法将 pgrep 输出正确地分配给 bash 脚本上的变量?](https://linux22.com/image/150223/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E6%97%A0%E6%B3%95%E5%B0%86%20pgrep%20%E8%BE%93%E5%87%BA%E6%AD%A3%E7%A1%AE%E5%9C%B0%E5%88%86%E9%85%8D%E7%BB%99%20bash%20%E8%84%9A%E6%9C%AC%E4%B8%8A%E7%9A%84%E5%8F%98%E9%87%8F%EF%BC%9F.png)
我正在尝试制作一个脚本,以便在 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不太可能为compton
1。
如果您想终止任何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