考虑到它的参数,如何检测bash脚本是不是已经在运行[重复]
Posted
技术标签:
【中文标题】考虑到它的参数,如何检测bash脚本是不是已经在运行[重复]【英文标题】:How to detect if a bash script is already running, considering its arguments [duplicate]考虑到它的参数,如何检测bash脚本是否已经在运行[重复] 【发布时间】:2021-10-29 06:57:11 【问题描述】:对不起我的英语不好;)
我需要检查一个脚本是否已经在运行。我不想使用锁定文件,因为它可能很棘手(即:如果我的脚本写了一个锁定文件,但崩溃了,我会认为它正在运行)。 我还需要考虑参数。 IE: 测试.sh 123 应该被认为是一个不同的过程 测试.sh 456
我试过了:
#!/bin/bash
echo "inside test.sh, script name with arguments: $0 +$*$"
echo " simple pgrep on script name with arguments:"
pgrep -f "$0 +$*$"
echo " counting simple pgrep on script name with arguments with wc -l"
echo $(pgrep -f "$0 +$*$" | wc -l)
echo " counting pgrep echo result with wc -w"
processes=$(pgrep -f "$0 +$*$")
nbProcesses=$(echo $processes | wc -w)
echo $nbProcesses
sleep 300
当我尝试时,我得到了这个结果:
[frederic.charrier@charrier tmp]$ /tmp/test.sh 123
inside test.sh, script name with arguments: /tmp/test.sh +123$
simple pgrep on script name with arguments:
123976
counting simple pgrep on script name with arguments with wc -l
2
counting pgrep echo result with wc -w
1
^Z
[1]+ Stoppé /tmp/test.sh 123
[frederic.charrier@charrier tmp]$ /tmp/test.sh 123
inside test.sh, script name with arguments: /tmp/test.sh +123$
simple pgrep on script name with arguments:
123976
124029
counting simple pgrep on script name with arguments with wc -l
3
counting pgrep echo result with wc -w
2
我的问题是:
当我第一次运行脚本时,它只运行一次。所以 pgrep 只返回一个结果:123976,这很好。但是为什么 123976 上的“wc -l”会返回 2? 当我第二次运行脚本时,我得到了同样奇怪的行为:pgrep 返回正确的结果,pgrep | wc -l 返回错误,“echo pgrep ... | wc -w”返回正确结果。为什么?【问题讨论】:
除了您要查找的命令之外,pgrep 命令是否有可能找到自己?您可以使用ps
进行检查,也可以使用| grep -v grep
从grep 命令中排除PID 来避免它。
顺便说一句,这似乎是特定于 Linux 的。我无法在 macOS 上重现。问题出在pgrep
还是wc
,我不知道。
如果您在两个链接问题的54个答案中都找不到您想要的解决方案,请说明原因,您的问题可以考虑重新开放。
对不起,如果它听起来像重复,但我想避免“羊群”解决方案。无论如何,一切都很好,因为@kamilcuk 的回答帮助我理解了替换后的“两个进程”计数:)
【参考方案1】:
如何检测 bash 脚本是否已经在运行
如果您意识到您的方法的缺点,使用pgrep
看起来不错。请注意,$0
和 $*
都可以在其中包含正则表达式语法的东西,你必须先将它们转义,我想我也会从一开始就使用 pgrep -f "^$0...
来匹配它。
为什么 123976 上的“wc -l”返回 2?
因为命令替换$(..)
会生成一个子shell,所以在执行pgrep
时会运行两个shell。
总的来说,echo $(cmd)
是一种反模式。只需运行它cmd
。
在某些情况下,例如当命令替换中只有一个命令时,bash 会优化并用命令本身替换 (exec
) 子shell,从而有效地消除子shell。这是一个优化。这就是processes=$(pgrep ..)
返回 1 的原因。
为什么?
还有一个进程正在运行。
【讨论】:
但是echo $(pgrep ...)
仍然只输出一个进程ID。以上是关于考虑到它的参数,如何检测bash脚本是不是已经在运行[重复]的主要内容,如果未能解决你的问题,请参考以下文章