this is my shell script
#!/bin/sh
echo "===="
echo $1
echo "===="
ps -ef | grep -w $1 | grep -v -e "grep"
echo "===="
echo $(ps -ef | grep -w $1 | grep -v -e "grep" | wc -l)
echo "===="
exit 0
then,i execute the shell script at command line.
./test.sh php-fpm
the result is:
====
php-fpm
====
0 986 984 0 4:43PM ?? 0:05.53 php-fpm
70 988 986 0 4:43PM ?? 0:00.00 php-fpm
70 989 986 0 4:43PM ?? 0:00.00 php-fpm
70 990 986 0 4:43PM ?? 0:00.00 php-fpm
0 984 1 0 4:43PM ttys000 0:00.01 sudo php-fpm
501 4098 827 0 10:24AM ttys001 0:00.00 /bin/sh ./test.sh php-fpm
====
7
====
so,my question is:why last output is 7 not 6?
thanks.
You can use command
ps -C $1 --no-headers
Updated code is
#!/bin/sh
echo "===="
echo $1
echo "===="
ps -C $1 --no-headers
#ps -lfC $1 --no-headers
echo "===="
COUNT=$(ps -C $1 --no-headers | wc -l)
echo $COUNT
echo "===="
exit 0
Run
sh /tmp/test.sh java
O/P
====
java
====
4969 ? 00:01:00 java
6884 ? 00:00:34 java
10200 ? 00:00:18 java
====
3
====
Related
I have simple unix shell script as follows. Which is giving different count for a service
#!/bin/bash
service=$1
ps -ef | grep $service | grep -v "grep" | wc -l
PROCESS_NUM=$(ps -ef | grep $service | grep -v "grep"| wc -l)
echo $PROCESS_NUM
In the above code below line gives output of 2.
ps -ef | grep $service | grep -v "grep" | wc -l
But when same line is assigned to variable as code below its giving output as 3.
PROCESS_NUM=$(ps -ef | grep $service | grep -v "grep"| wc -l)
echo $PROCESS_NUM
Why this is getting increased by 1 and how to tackle it.
You can see what is happening if the script tees the output to a file before counting the lines and then displaying the output after:
#!/bin/bash
service=$1
echo Directly in Script:
ps -ef | grep $service | grep -v grep | tee test.txt | wc -l
cat test.txt
echo Inside Subshell:
RESULT=$(ps -ef | grep $service | grep -v grep | tee test.txt | wc -l)
echo $RESULT
cat test.txt
When the output of a command is captured, bash starts another shell to run the command - but that subshell also shows up in the process list.
When I run that script I get:
$ ./test.sh lca
Directly in Script:
2
gcti 4268 1 0 2018 ? 21:59:03 ./lca 4999
t816826 9159 7009 0 09:22 pts/1 00:00:00 /bin/bash ./test.sh lca
Inside Subshell:
3
gcti 4268 1 0 2018 ? 21:59:03 ./lca 4999
t816826 9159 7009 0 09:22 pts/1 00:00:00 /bin/bash ./test.sh lca
t816826 9166 9159 0 09:22 pts/1 00:00:00 /bin/bash ./test.sh lca
I want my script to check if it's already running in another instance:
$ cat test.sh
#!/bin/bash
ps -ef | grep -v grep | grep -i "test.sh" | grep bash
ps -ef | grep -v grep | grep -i "test.sh" | grep -c bash
if [ `ps -ef | grep -v grep | grep -i "test.sh" | grep -c bash` -gt 1 ]; then echo "There's another instance running."
else echo "Only this instance is running."
fi
However the output is
$ ./test.sh
noes 9503 7494 0 09:32 pts/1 00:00:00 /bin/bash ./test.sh
1
There's another instance running.
Clearly, 1 is not greater than 1, so why is the if condition triggered?
Thanks
From test man page:
INTEGER1 -gt INTEGER2
INTEGER1 is greater than INTEGER2
So the answer is no, -gt is not triggered when values are equal. In fact, as you can see if you modify the script in this way:
$ cat test.sh
#!/bin/bash
ps -ef | grep -v grep | grep -i "test.sh" | grep bash
ps -ef | grep -v grep | grep -i "test.sh" | grep -c bash
STRINGS=`ps -ef | grep -v grep | grep -i "test.sh"`
echo "$STRINGS"
COUNT=`ps -ef | grep -v grep | grep -i "test.sh" | grep -c bash`
echo $COUNT
if [ `ps -ef | grep -v grep | grep -i "test.sh" | grep -c bash` -gt 1 ]; then echo "There's another instance running."
else echo "Only this instance is running."
fi
You get this:
$ ./test.sh
lucio 5097 4736 0 10:10 pts/2 00:00:00 /bin/bash ./test.sh
1
lucio 5097 4736 0 10:10 pts/2 00:00:00 /bin/bash ./test.sh
lucio 5106 5097 0 10:10 pts/2 00:00:00 /bin/bash ./test.sh
2
There's another instance running.
If you modify the script in this way, it will work:
#!/bin/bash
ps -ef | grep -v grep | grep -i "test.sh" | grep bash
pgrep -c test.sh
if [ $(pgrep -c test.sh) -gt 1 ]; then
echo "There's another instance running."
else
echo "Only this instance is running."
fi
This is the output:
$ ./test.sh
lucio 5197 4736 0 10:17 pts/2 00:00:00 /bin/bash ./test.sh
1
Only this instance is running.
Note the use $() instead of backticks. Check this answer for this change.
crontab looks as below:
SHELL=/bin/bash
* * * * * /home/zaks/influx_rabbitmq_restorer.sh > /home/zaks/crontab.txt 2>&1
influx_rabbitmq_restorer.sh:
ps -aux | grep -v grep | grep rabbitmq_restorer
RESULT=$?
echo $RESULT
if [ $RESULT -eq 0 ]; then
echo "running"
else
echo "not running"
(nohup python -u /home/zaks/rabbitmq_restorer.py )
fi
When I manually run the script /home/zaks/influx_rabbitmq_restorer.shthe result is 1 ("not running").
But cronjob log at /home/zaks/crontab.txt shows:
zaks 11612 0.0 0.0 12504 2936 ? Ss 03:15 0:00 /bin/bash -c /home/zaks/influx_rabbitmq_restorer.sh > /home/zaks/crontab.txt 2>&1
zaks 11613 0.0 0.0 12516 2388 ? S 03:15 0:00 /bin/bash -c /home/zaks/influx_rabbitmq_restorer.sh > /home/zaks/crontab.txt 2>&1
0
running
cronjob is unable to detect rabbitmq_restorer process.
Edit first line of the script to be like:
ps -aux | grep -v grep | grep -v influx_rabbitmq_restorer.sh| grep rabbitmq_restorer
I have a small script to check if a service is running in bash
#!/bin/bash
countlines=""$(ps -ef | grep netdata | grep -v grep | wc -l)
echo $countlines >> mylog.log
if [ ${countlines} -lt 3 ];then
sudo /bin/systemctl restart netdata
fi
The problem is when I issue a ps -ef | grep netdata | grep -v grep | wc -l at the command line the result is always 3 but mylog.log is:
6
[update: added filtered ps -ef results]
forge#reportserver:~ ps -ef | grep netdata
netdata 22308 1 0 08:38 ? 00:00:37 /usr/sbin/netdata -D
netdata 22386 22308 0 08:38 ? 00:00:58 /usr/libexec/netdata/plugins.d/apps.plugin 1
netdata 47045 22308 0 11:38 ? 00:00:02 bash /usr/libexec/netdata/plugins.d/tc-qos-helper.sh 1
forge 52028 27902 0 12:34 pts/8 00:00:00 grep --color=auto netdata
why such a discordance?
split into 2 commands to see why:
ps_grep_output=$(ps -ef | grep netdata | grep -v grep)
echo "$ps_grep_output" >> mylog.log
countlines=$(wc -l <<< "$ps_grep_output")
echo "$countlines" >> mylog.log
I was trying to prevent a script from being run by more than one user simultaneously and did not want to use commands only available on some OS'es or shells (pgrep, pidof, ...) and bumped into an issue that I am not sure whether it is a bug or not...
Please ignore the specifics I used in my script: the issue is about the command substitution in bash when using ps.
When I run the following (note the shebang in ksh):
#!/bin/ksh
CMD=`basename $0`
echo $CMD
ps -ef | grep "$CMD"
ps -ef | grep "$CMD" | wc -l
RUNS=`ps -ef | grep "$CMD" | wc -l`
echo $RUNS
if [ $RUNS -gt 2 ]; then
echo The script is currently being run by another user.
#exit 1
fi
RUNS=`ps -ef | grep "$CMD"`
echo "$RUNS"
RUNS=`echo "$RUNS" | wc -l`
echo $RUNS
if [ $RUNS -gt 2 ]; then
echo The script is currently being run by another user.
#exit 1
fi
ps -ef | grep "$CMD" | wc -l > lock
RUNS=`cat lock`
echo $RUNS
if [ $RUNS -gt 2 ]; then
echo The script is currently being run by another user.
exit 1
fi
I get this correct output:
testksh.sh7
abriere 19126 5669 0 14:15 pts/21 00:00:00 /bin/ksh ./testksh.sh7
abriere 19129 19126 0 14:15 pts/21 00:00:00 grep testksh.sh7
2
2
abriere 19126 5669 0 14:15 pts/21 00:00:00 /bin/ksh ./testksh.sh7
abriere 19137 19126 0 14:15 pts/21 00:00:00 grep testksh.sh7
2
2
I get this after replacing the shebang for bash and renaming the script accordingly:
testbash.sh7
abriere 5631 5669 0 14:12 pts/21 00:00:00 /bin/bash ./testbash.sh7
abriere 5634 5631 0 14:12 pts/21 00:00:00 grep testbash.sh7
2
3
The script is currently being run by another user.
abriere 5631 5669 0 14:12 pts/21 00:00:00 /bin/bash ./testbash.sh7
abriere 5643 5631 0 14:12 pts/21 00:00:00 /bin/bash ./testbash.sh7
abriere 5645 5643 0 14:12 pts/21 00:00:00 grep testbash.sh7
3
The script is currently being run by another user.
2
Note the extra line in the ps output.
The following line in bash:
RUNS=`ps -ef | grep "$CMD" | wc -l`
does not return the same value as:
ps -ef | grep "$CMD" | wc -l
Ksh does not have this issue.
As you can see, there are workarounds: I use one in the last section of my script.
I ran the scripts on Linux, AIX and SunOS and they gave me the same results; only Cygwin did not, but the ps command does not return the script in either shell.
Is this a bug? Even if bash runs command substitution within a subshell (see question 21331042), I still consider the variable assigned the value of the command substitution should return the same value as the command itself...