开发者

Continue script if only one instance is running? [duplicate]

开发者 https://www.devze.com 2022-12-25 01:16 出处:网络
This question already has answers here: Quick-and-dirty way to ensure only one instance of a shell script is running at a time
This question already has answers here: Quick-and-dirty way to ensure only one instance of a shell script is running at a time (42 answers) Closed 5 years ago.

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开发者_StackOverflow 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 -w returns 1 if I run it inside of script, so I don't see any reason why basically if [ 1 -eq 1 ] wouldn't pass.

Thanks a lot!


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

#!/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..."


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.


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

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


If you use the -o option 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:

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


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


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##*/}


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:

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

精彩评论

暂无评论...
验证码 换一张
取 消