BASH - Check that it is not running the same script - bash

I have a script /root/data/myscript
and when I run /root/data/myscript
I do not know how to determine if you have one running
does anyone know?
I tried
if [[ "$(pidof -x /root/data/myscript | wc -w)" > "1" ]]
then echo "This script is already running!"
fi
thank you

This should work.
if [[ "$(pgrep myscript)" ]]
then echo "This script is already running!"
fi

This could work to check whether the script is already running or not.
if [[ "$(ps -ef | grep "/root/data/myscript" | grep -v "grep")" ]] ; then
echo "This script is already running!"
fi
Try this one.

Related

Why is "if [ -z "ls -l /non_existing_file 2> /dev/null" ] not true [duplicate]

This question already has answers here:
Test if a command outputs an empty string
(13 answers)
Closed 2 years ago.
I want to check if an external drive is still plugged in by checking /dev/disk/by-uuid/1234-5678.
However, I know that this could be done much easier with:
if ! [ -e "/non_existing_file" ]
echo "File dont exists anymore"
fi
But I still want to know why the script in the Title dont work. Is it because of the exit code of ls?
Thanks in advance.
It looks like the ls -l /nonexisting is a string that is not executed. This should work correctly if it is executed in a subshell.
Compare the example in the title:
if [[ -z "ls -l something.txt 2> /dev/null" ]]; then
echo "file does not exist"
fi
... with this version that returns as expected:
if [[ -z "$(ls -l something.txt 2> /dev/null)" ]]; then
echo "file does not exist"
fi

How to avoid the same bash script from running more than once when its called from another script?

I have a script called "upcall" which calls 4 different scripts. In upcall I call them in the way show. The first part of the script works when I run the script directly (bash upload_cloud1), but does not when its called from the script below. Im sure there is a way to fix this, but just not sure what it is. I have it currently setup in crontab to run every 15 mins to check for used space.
#!/bin/bash
if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then
echo "This script is already running with PID `pidof -x $(basename $0) -o %PPID`"
exit; fi
count=$(</opt/rclone/scripts/upcount)
size=$(df -k /dev/sda2 | tail -1 | awk '{print $3}')
if [ "$size" -gt "234003200" ]; then
bash /opt/rclone/scripts/upload_cloud${count}
else
echo "Not full yet"
fi

SoF2 shell script not running

I've got the following code in my shell script:
SERVER=`ps -ef | grep -v grep | grep -c sof2ded`
if ["$SERVER" != "0"]; then
echo "Already Running, exiting"
exit
else
echo "Starting up the server..."
cd /home/sof2/
/home/sof2/crons/start.sh > /dev/null 2>&1
fi
I did chmod a+x status.sh
Now I try to run the script but it's returning this error:
./status.sh: line 5: [1: command not found
Starting up the server...
Any help would be greatly appreciated.
Could you please try changing a few things in your script as follows and let me know if that helps you?(changed back-tick to $ and changed [ to [[ in code)
SERVER=$(ps -ef | grep -v grep | grep -c sof2ded)
if [[ "$SERVER" -eq 0 ]]; then
echo "Already Running, exiting"
exit
else
echo "Starting up the server..."
cd /home/sof2/
/home/sof2/crons/start.sh > /dev/null 2>&1
fi
The problem is with the test command. "But", I hear you say, "I am not using the test command". Yes you are, it is also known as [.
if statement syntax is if command. The brackets are not part of if syntax.
Commands have arguments separated (tokenized) by whitespace, so:
[ "$SERVER" != "0" ]
The whitespace is needed because the command is [ and then there are 4 arguments passed to it (the last one must be ]).
A more robust way of comparing numerics is to use double parentheses,
(( SERVER == 0 ))
Notice that you don't need the $ or the quotes around SERVER. Also the spacing is less important, but useful for readability.
[[ is used for comparing text patterns.
As a comment, backticks ` ` are considered deprecated because they are difficult to read, they are replaced with $( ... ).

IF statement in script and in a single command line

My script below checks for the instance of opened window in X server and it prints some info in the terminal depending on the state.
#!/bin/bash
if [[ -z $(xwininfo -tree -root | grep whatsapp | grep chromium) ]]
then
echo "IT DOES NOT EXIST";
else
echo "IT EXIST";
fi
When I try to rewrite this into a one line terminal command I do it like this:
if -z $(xwininfo -tree -root | grep whatsapp | grep chromium); then echo "IT DOES NOT EXIST"; else echo "IT EXIST"; fi
this returns error and a wrong state...
bash: -z: command not found
IT EXISTS
Does anyone have any advice? I tried asking the ShellCheck but it says I have everything in order...
Correctly following the advice from http://shellcheck.net/ would have looked like the following:
if xwininfo -tree -root | grep whatsapp | grep -q chromium; then
echo "IT DOES NOT EXIST";
else
echo "IT EXIST";
fi
...thus, in one-liner form:
if xwininfo -tree -root | grep whatsapp | grep -q chromium; then echo "IT DOES NOT EXIST"; else echo "IT EXIST"; fi
See the wiki page for SC2143, the shellcheck warning you received.
I got messed with an online bash code checker which stated that [[ and ]] are not needed. This worked for me:
if [[ -z $(xwininfo -tree -root | grep whatsapp | grep chromium) ]]; then chromium --app=\\"https://web.whatsapp.com/\\"; fi & if [[ -z $(xwininfo -tree -root | grep skype | grep chromium) ]]; then chromium --app=\\"https://web.skype.com/en/\\"; fi & if [[ -z $(xwininfo -tree -root | grep Viber) ]]; then viber; fi

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

This question already has answers here:
Quick-and-dirty way to ensure only one instance of a shell script is running at a time
(43 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 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"

Resources