RUNNING_APPS=$(pgrep -f "somePattern")
echo $?
#results in
1
How can I make my command pass with exit code 0?
On my Arch system, with the pgrep from procps-ng, I see this in man pgrep:
EXIT STATUS
0 One or more processes matched the criteria. For
pkill the process must also have been success‐
fully signalled.
1 No processes matched or none of them could be
signalled.
2 Syntax error in the command line.
3 Fatal error: out of memory etc.
So this is just the way it is: pgrep will exit with 1 if everything worked fine but there were no processes matching the search string. This means you will need to use a different tool. Perhaps something like Kusalananda suggested in the comments and ilkkachu posted as an answer:
running_apps=$(pgrep -f "somePattern" || exit 0)
But a better approach, IMO, would be to change your script. And instead of using set -e, have it exit manually at the important steps. Then, you can use something like this:
running_apps=$(pgrep -fc "somePattern")
if [ "$running_apps" = 0 ]; then
echo "none found"
else
echo "$running_apps running apps"
fi
pgrep ... || exit 0 in the command substitution. Or don't use set -e.
– Kusalananda
Aug 11 '20 at 13:52
pgrep. What OS are you on?
– terdon
Aug 11 '20 at 13:57
... | grep -v grep returns with an error if there are no lines without grep in them. Just go with || true to suppress the error exit.
– ilkkachu
Aug 11 '20 at 14:33
ps aux | grep one | grep two? That said, yes the || exit 0 trick is indeed a better approach.
– terdon
Aug 11 '20 at 14:41
ps aux | grep xterm | grep -v xterm and there's no xterm running on the system, then the first grep only matches the line for itself (or not even that), and the second doesn't select (print) anything, so it exits 1.
– ilkkachu
Aug 11 '20 at 14:46
With set -e, commands that on the left side of the AND (&&) or OR (||) operators don't cause the shell to exit, so you can suppress the error by adding || true.
So this should output 0 regardless of the processes found (and not exit before outputting it):
set -e
RUNNING_APPS=$(pgrep -f "somePattern" || true)
echo $?
set -eflag which fails after this command. Echo is added just to illustrate behavior. – makozaki Aug 11 '20 at 13:34pgrepbehaves so if you must useset -e, then you cannot usepreplike this. Make sure to mention what operating system you are running. Also, a point on style: avoid using CAPS for variable names in shell scripts, that is bad practice since global environment variables are capitalized and this can cause variable name collisions with unexpected consequences. – terdon Aug 11 '20 at 13:36pgrep -f whatever || trueshould return 0 and not trip the -e action. – Paul_Pedant Aug 11 '20 at 14:27