LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 05-30-2019, 08:01 AM   #1
jose_spain
LQ Newbie
 
Registered: Apr 2018
Posts: 10

Rep: Reputation: Disabled
Bash script to count number of executions instances does not work.


I am writing a script that detects if there is any instance of it already running and shows on screen the number of instances.

The content of the "detect_itself.sh" script is:
#!/bin/sh

INSTANCES_NUMBER=`ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`
echo "Number of detect_itself.sh instances running now =" $INSTANCES_NUMBER

echo "Second method:"
ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l

echo "Third method:"
echo `ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`

echo "Please, press a key"
read -r key
When executing the script it shows by screen:

Number of detect_itself.sh instances running now = 2
Second method:
1
Third method:
2
Please, press a key


But I expected it to show:

Number of detect_itself.sh instances running now = 1
Second method:
1
Third method:
1
Please, press a key



I do not understand why if I execute ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l it returns the value 1, but if I save this value in a variable and show it with echo it shows 2.

Last edited by jose_spain; 05-30-2019 at 08:02 AM.
 
Old 05-30-2019, 10:11 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,039

Rep: Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347
you need to use pgrep instead of that ps | grep | grep | wc chain.
Also please use code tags to keep formatting of your original script.

The test you made shows clearly the method you use (that pipe chain) is not reliable.
 
Old 05-30-2019, 10:59 AM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,783

Rep: Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936
Command substitution i.e $(command) or `command` starts a child process.

This is why method 1 and 3 return 2 and not 1.
 
1 members found this post helpful.
Old 05-31-2019, 05:21 AM   #4
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
seems too complex, too many pipes.

questions:
how do you start the script?
is it in your $PATH?
is it always started with the same command?

maybe
Code:
pidof -x "$0"
is enough?
 
Old 05-31-2019, 07:34 AM   #5
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Looking at this and thinking what good, or real world usage could this possibly be used for, a script that checks itself to see if it has another one running or not, if yes how many?

then I remember something I wrote in a script long long ago to see if more than one (child) was running. this is a snippet of it. Maybe (hopefully) you can figure out how to do something with it to get what you're looking for. It actually goes in line with what pan64 is telling you, you need to use.
Code:
[ $(pgrep -u $USER $appname | wc -l) -ge 2 ]

Last edited by BW-userx; 05-31-2019 at 07:40 AM.
 
Old 06-07-2019, 12:55 AM   #6
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,369

Rep: Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753
A classic usage example is a cron job that runs so frequently that successive runs may overlap if eg the amt of incoming data grows enough (& it is designed to single task).
There are a few ways of checking this situation, but checking the process table is more reliable/accurate than lock files - I've seen that fail a few times.
 
Old 06-07-2019, 12:32 PM   #7
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218
The backticks spawn a sub shell. Dependent on your shell interpreter, it can put another process in the proctable that can match your grep.
As suggested already, pgrep is the way out.
Code:
pgrep -x detect_itself.sh
Or
Code:
pgrep -f detect_itself.sh
Furthermore,
| wc -l is a builtin: pgrep -c ...
 
Old 06-12-2019, 04:12 AM   #8
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
Quote:
Originally Posted by MadeInGermany View Post
Furthermore,
| wc -l is a builtin: pgrep -c ...
in recent bash versions, neither wc nor pgrep are builtins.

OP seems to have gone AWOL.

in any case, i use this in one of my scripts:
Code:
function only_me_or_exit {
# argument: pidfile
# make sure only 1 instance is running
touch "$1"
read lastPID < "$1"
# if lastPID is not null and a process with that pid exists , exit
[ ! -z "$lastPID" -a -d /proc/$lastPID ] && { echo "An instance of $me is already running with pid $lastPID." ; exit 1 ; }
# else - save my pid in the lock file, and continue
echo $$ > "$1"
}
been a while since i wrote it, code might be inferior.
 
  


Reply

Tags
bash scripting, linux



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Which options can i use in "flock" to stop multiple script executions. varma6009 Programming 3 12-19-2014 09:18 AM
sendmail-2: Wrong number of instances of process sendmail:, expected instances equal maxymaxymaxymaxymaxy Linux - Newbie 1 06-15-2011 10:51 AM
Slackware64 do nothing on some commands executions ooslack Slackware 2 09-06-2009 09:49 AM
Command Line Executions Lion0928 Linux - Newbie 3 01-22-2005 06:43 AM
program executions thru prompt kev^ Linux - General 4 03-14-2004 11:59 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 07:30 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration