bash 如果只有一个实例正在运行,是否继续脚本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2530114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:52:55  来源:igfitidea点击:

Continue script if only one instance is running?

bashif-statement

提问by Gargauth

now this is embarrassing. I'm writing quick script and I can't figure out why this statement don't work.

现在这很尴尬。我正在编写快速脚本,但我不明白为什么这个语句不起作用。

if [ $(pidof -x test.sh | wc -w) -eq 1 ]; then echo Passed; fi

I also tried using back-ticks instead of $() but it still wouldn't work.

我也尝试使用反引号代替 $() 但它仍然不起作用。

Can you see what is wrong with it? pidof -x test.sh | wc -wreturns 1 if I run it inside of script, so I don't see any reason why basically if [ 1 -eq 1 ]wouldn't pass.

你能看出它有什么问题吗?pidof -x test.sh | wc -w如果我在脚本中运行它,则返回 1,所以我没有看到任何基本if [ 1 -eq 1 ]不会通过的原因。

Thanks a lot!

非常感谢!

采纳答案by Kevin Little

Jefromi is correct; here is the logic I think you want:

Jefromi 是正确的;这是我认为你想要的逻辑:

#!/bin/bash
# this is "test.sh"

if [ $(pidof -x test.sh| wc -w) -gt 2 ]; then 
    echo "More than 1"
    exit
fi

echo "Only one; doing whatever..."

回答by Cascabel

Ah, the real answer: when you use a pipeline, you force the creation of a subshell. This will always cause you to get an increased number:

啊,真正的答案是:当您使用管道时,您会强制创建一个子外壳。这将始终导致您获得增加的数字:

#!/bin/bash

echo "subshell:"
np=$(pidof -x foo.bash | wc -w)
echo "$np processes"   # two processes

echo "no subshell:"
np=$(pidof -x foo.bash)
np=$(echo $np | wc -w)
echo "$np processes"   # one process

I'm honestly not sure what the shortest way is to do what you really want to. You could avoid it all by creating a lockfile - otherwise you probably have to trace back via ppid to all the top-level processes and count them.

老实说,我不确定做您真正想做的事情的最短方法是什么。您可以通过创建锁定文件来避免这一切 - 否则您可能必须通过 ppid 追溯到所有顶级进程并对其进行计数。

回答by ghostdog74

you don't have to pass the result of pidof to wcto count how many there are..use the shell

您不必将 pidof 的结果传递wc给计算有多少..使用外壳

r=$(pidof -x -o $$ test.sh)
set -- $r
if [ "${#@}" -eq 1 ];then
 echo "passed"
else
 echo "no"
fi

回答by musashiXXX

Here's how I would do it:

这是我将如何做到的:

if [ "`pgrep -c someprocess`" -gt "1" ]; then
  echo "More than one process running"
else
  echo "Multiple processes not running"
fi

回答by Zrin

If you don't want to use a lockfile ... you can try this:

如果您不想使用锁文件……您可以试试这个:

#!/bin/bash

if [[ "$(ps -N -p $$ -o comm,pid)" =~ $'\n'"${0##*/}"[[:space:]] ]]; then
    echo "aready running!"
    exit 1
fi

PS: it might need adjustment for a weird ${0##*/}

PS:它可能需要调整一个奇怪的 ${0##*/}

回答by Paused until further notice.

If you use the -ooption to omit the PID of the script ($$), then only the PID of the subshell and any other instances of the script (and any subshells they might spawn) will be considered, so the test will pass when there's only one instance:

如果您使用-o选项省略脚本 ( $$) 的 PID,则只会考虑子外壳的 PID 和脚本的任何其他实例(以及它们可能产生的任何子外壳),因此当只有一个时,测试将通过实例:

if [ $(pidof -x -o $$ test.sh | wc -w) -eq 1 ]; then echo Passed; fi

回答by PePa

Just check for the existence of any one (or more) process identified as test.sh, the return code will be 1 if none are found:

只需检查是否存在标识为 test.sh 的任何一个(或多个)进程,如果没有找到,则返回码将为 1:

pidof -x test.sh >/dev/null && echo "Passed"