3
RUNNING_APPS=$(pgrep -f "somePattern")
echo $?

#results in
1

How can I make my command pass with exit code 0?

makozaki
  • 133
  • What are you trying to do exactly? Please [edit] your question and give us some context. Why are you checking the exit status of the command? – terdon Aug 11 '20 at 13:32
  • I've got script with set -e flag which fails after this command. Echo is added just to illustrate behavior. – makozaki Aug 11 '20 at 13:34
  • 2
    Please *edit* your question to add this then. And give us enough context so we can offer an alternative: this is how pgrep behaves so if you must use set -e, then you cannot use prep like 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:36
  • 1
    pgrep -f whatever || true should return 0 and not trip the -e action. – Paul_Pedant Aug 11 '20 at 14:27

2 Answers2

3

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
terdon
  • 242,166
  • 3
    Or just use pgrep ... || exit 0 in the command substitution. Or don't use set -e. – Kusalananda Aug 11 '20 at 13:52
  • pgrep -fc is just a pseudo-code? I get invalid option -- 'c' – makozaki Aug 11 '20 at 13:54
  • @MarcinKozakiewicz that's why I asked you to tell us your operating system. It looks like you are using a different version of pgrep. What OS are you on? – terdon Aug 11 '20 at 13:57
  • 1
    ... | 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
  • @ilkkachu is that ever possible given that the command is part of 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
  • @terdon, well, if you go 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
  • @ilkkachu duh, of course. Thanks. – terdon Aug 11 '20 at 14:50
3

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 $?
ilkkachu
  • 138,973