0

I have put together a bash script to identify a process and echo if process is running or not accordingly. My script:

#!/bin/bash

var1=$(ps -ef | grep -v grep | grep crond)
echo $var1
if [$var1]
then
echo "The Process is Running"
else
echo "The process is not running"
fi

I am getting output out of Var1 variable but code still breaks at my 'if-condition' with this error:

$ ./test.sh
spidmd07 3034 4649 0 2017 ? 00:00:00 crond root 4649 1 0 2017 ? 00:00:02 crond spidmd01 5477 4649 0 2017 ? 00:00:00 crond
./test.sh: line 6: [spidmd07: command not found
The process is not running

spidmd07 in this case is another user which is running 1 instance of "Crond" process.

Moose
  • 751
  • 22
  • 42
  • `grep -v grep` - You do not need this – Ed Heal Jan 09 '18 at 03:30
  • In fact, if you're going to run a `|grep` on the output of `ps -ef`, you'll find that `grep` is in the output of `ps -ef`, I think it's pretty cute to remove it. – JawguyChooser Jan 09 '18 at 04:01
  • Learn to use http://shellcheck.net **before** you post your code here ;-) . When you use shellcheck, you need to include a proper "she-bang" line as the first line, usually `#!/bin/bash` . AND avoid the top 10 shell script beginner mistakes by reading https://stackoverflow.com/tags/bash/info multiple times. Good luck. – shellter Jan 09 '18 at 04:16

3 Answers3

3

Yah, you've got the syntax of the brackets around if wrong. You can use [ or [[ but both require a space after them (see man [ for more info on the classic test program).

But, I assume you want this to work for more than just crond so I made it into a script with an arg.

$ cat is_cmd_running.sh 
#!/bin/bash

psout=$(ps -ef | grep -v grep | grep -v $0 | grep $1) 
if [[ -z ${psout:-} ]]; then
  echo "$1 is not running"
else
  echo "$1 is running"
fi

Note that in addition to the filter -v grep, I also had to filter -v $0 or else the ps of the program it self spuriously matches. This program works on my system:

$ bash is_cmd_running.sh firefox
firefox is running
$ bash is_cmd_running.sh konqueror
 konqueror is not running

There's also a simpler version where you don't test a variable, but just evaluate the return code from the last grep. The normal thing to do is to use the -q flag to make grep quiet then just evaluate the return code. This is more traditional, I think, in shell scripts:

$ cat is_cmd_running.sh 
#!/bin/bash

if ps -ef | grep -v grep | grep -v $0 | grep -q $1 ; then
  echo "$1 is running"
else
  echo "$1 is not running"
fi

And this also works:

$ bash is_cmd_running.sh konqueror
konqueror is not running
$ bash is_cmd_running.sh firefox
firefox is running

EDIT:

@tripleee makes a good point about the reimplementation of standard commands and the importance of linters (thankfully, I have shellcheck installed). So, I present a final version, accepted by shellcheck, which demonstrates how to use if directly on a process' return code without assigning output to a variable:

$ cat is_cmd_running.sh 
#!/bin/bash
if pgrep "$1" >/dev/null ; then
  echo "$1 is running"
else
  echo "$1 is not running"
fi
$ shellcheck is_cmd_running.sh
$ echo $?
0
$

:)

JawguyChooser
  • 1,816
  • 1
  • 18
  • 32
  • Reimplementing `pidof` poorly is an extremely common antipattern. There must be hundreds if not thousands of questions about this on Stack Overflow alone. This answer is not partcularly awful (so I haven't downvoted) but really, at least it should pass http://shellcheck.net/ – tripleee Jan 09 '18 at 04:48
  • @tripleee I'm not saying this is a great implementation of `pidof`. I took the OPs question to be about their failed usage of `[`. I tried to show them how to use `[` or `[[`, and to show them that you can evaluate `grep -q` return code without saving any output to a variable. – JawguyChooser Jan 09 '18 at 05:13
  • All good now; thanks for the update. Finding good duplicates on Stack Overflow is unreasonably hard (though I hear they are working on better search again now) so we have tried to collect some good canonicals in the [Stack Overflow `bash` tag info page](/tags/bash/info) -- maybe check that out before attempting to answer a very common type of question. Though this particular category of question still requires a lot of consolidation and cleanup to reduce duplicated and sometimes outright invalid answers. – tripleee Jan 09 '18 at 05:21
2

It's always troublesome to grep ps for a process. Sort of like the Heisenberg uncertainty principle; your grep process effects the results by showing up with the one you want.

If you want to use grep, you can tweak the pattern so the grep process doesn't show up with something like grep [c]ron. Or better, use the ps -C option to have ps select by command name then skip grep:

if [ -n "$(ps -C crond -o pid=)" ]; then
    # if the ps command returns any string ...
    echo "The Process is Running"
else
    echo "The process is not running"
fi

The -o option lets you choose what is printed. In this case, just the process id is all we need.

Cole Tierney
  • 9,571
  • 1
  • 27
  • 35
  • I rather used [c]rond and it worked for me. Dint know that grep by default uses POSIX basic regular expression. – Moose Jan 09 '18 at 04:20
0

Try following and let me know if this helps you. Where I changed [$var] to [[ -n "$var" ]] in if condition.

#!/bin/bash

var1=$(ps -ef | grep -v grep | grep crond)
echo "$var1"
if [[ -n "$var1" ]]
then
    echo "The Process is Running"
else
    echo "The process is not running"
fi
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • Still fails to enter the 'if' condition: ./test.sh spidmd07 3034 4649 0 2017 ? 00:00:00 crond root 4649 1 0 2017 ? 00:00:02 crond spidmd01 5477 4649 0 2017 ? 00:00:00 crond ./test.sh: line 6: if[ -n spidmd07 3034 4649 0 2017 ? 00:00:00 crond root 4649 1 0 2017 ? 00:00:02 crond spidmd01 5477 4649 0 2017 ? 00:00:00 crond ]: command not found ./test.sh: line 7: syntax error near unexpected token `then' ./test.sh: line 7: `then' – Moose Jan 09 '18 at 03:38
  • @RiteshThakur, when I checked in my Linux system it is working fine. Can you check if no garbage characters are there on your system by doing `cat -v test.sh` once? Also try to put `set -x` in starting of your script too. Let me know how it goes then. – RavinderSingh13 Jan 09 '18 at 03:49
  • There are no garbage characters. After putting "set -x" , still my if condition breaks. – Moose Jan 09 '18 at 03:59
  • @RiteshThakurm I could see in your posted error that still you are using `[` single did you change `[` to `[[` and `]` to `]]` in your code? – RavinderSingh13 Jan 09 '18 at 04:06
  • it dint work with that as well. – Moose Jan 09 '18 at 04:08