I am trying to find the number of a particular process in bash using if condition as
if ps auwx | grep -v grep | grep -ic python -le 2; then echo error; else echo no_error; fi
and I am getting output as
grep: python: No such file or directory
no_error
The one-liner seems to break if I use pipe, and no error is thrown if I omit pipe, and it doesn't matter if I use the absolute path to grep either.I cannot get the required result without the pipe. What am I doing wrong here? I can get this done in a script file, by breaking it into variables and then doing comparing it, but I was using this as an exercise to learn bash. Any help is greatly appreciated.
First of all, the syntax of if
command is:
if cmd; then
# cmd exited with status 0 (success)
else
# cmd exited with status >0 (fail)
fi
The cmd
above is the so-called list - a sequence of pipelines. Each pipeline is a sequence of commands separated with |
.
The -le
operator is interpreted only by the test
command (also known as [
, or [[
), not by the if
command.
So, when you say:
if ps auwx | grep -v grep | grep -ic python -le 2; then ... fi
you actually call grep
with arguments:
grep -ic python -le 2
And since -e
is used to specify the search pattern, the argument python
is interpreted as a filename of the file to search for pattern 2
. That's why grep
tells you it can't find file named python
.
To test the output of a command pipeline in if
, you can use the command substitution inside the [[
/[
/test
(as the other answer suggests):
if [[ $(ps auwx | grep -v grep | grep -ic python) -le 2 ]]; then ... fi
or, within (( .. ))
, with implicit arithmetic comparisons:
if (( $(ps auwx | grep -v grep | grep -ic python) <= 2 )); then ... fi
using a command substitution in a condition
if [[ $(ps ...) -le 2 ]]; then
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With