59

I have a bash script with the following:

#!/bin/bash -e

egrep "^username" /etc/passwd >/dev/null 
if[ $? -eq 0 ] 
then 
  echo "doesn't exist" 
fi

This script will not run without the -e. What does the -e do for this script? Also, what does the $? do in this context?

6
  • 1
    Odd. No -e in the man page (I really want to see an answer address this). $? contains the last exit code (that of the egrep process spawned above).
    – pst
    Commented Jun 30, 2011 at 19:46
  • 4
    @pst: -e is documented under set. Commented Jun 30, 2011 at 19:50
  • You could simplify your script by doing this: if egrep -q "^username" /etc/passwd ; then echo "doesn't exist" ; fi
    – bollovan
    Commented Jul 3, 2011 at 10:17
  • 3
    You're missing a space between if and [. This script won't work with -e, because if grep doesn't find anything then under -e the script will terminate right there. Without -e, you've got the message backwards: a status ($?) of 0 means that grep did find the user. Note that this should be `grep '^username:', by the way (what if there's another user with a longer name?). Commented Jul 3, 2011 at 19:27
  • 3
    Will #/bin/bash -e have the same effect as #/bin/bash on line #1 and set -e on line #2 ?
    – blong
    Commented May 30, 2014 at 3:32

3 Answers 3

53

Your post actually contains 2 questions.

  1. The -e flag instructs the script to exit on error. More flags

    If there is an error it will exit right away.

  2. The $? is the exit status of the last command. In Linux an exit status of 0 means that the command was successful. Any other status would mean an error occurred.

To apply these answers to your script:

egrep "^username" /etc/passwd >/dev/null

would look for the username in the /etc/passwd file.

  • If it finds it then the exit status $? will be equal to 0.

  • If it doesn't find it the exit status will be something else (not 0). Here, you will want to execute the echo "doesn't exist" part of the code.

Unfortunately there is an error in your script, and you would execute that code if the user exists - change the line to

if [ $? -ne 0 ]

to get the logic right.

However if the user doesn't exist, egrep will return an error code, and due to the -e option the shell will immediately exit after that line, so you would never reach that part of the code.

3
  • In addition, you can make the script work correctly without the -e by replacing the first two lines with if egrep "^username" /etc/passwd >/dev/null.
    – RetroX
    Commented Jun 30, 2011 at 19:50
  • 1
    Why is no set required though? :-/
    – pst
    Commented Jun 30, 2011 at 20:44
  • 1
    @pst: Because the -e is given to bash as a command-line argument. All options listed under set are also accepted by bash in its command line – note the first sentence in section Options of the manual page. Commented Jul 3, 2011 at 18:40
19

All the bash command line switches are documented in man bash.

      -e      Exit  immediately  if a pipeline (which may consist of a
              single simple command),  a subshell command enclosed  in
              parentheses,  or one of the commands executed as part of
              a command list enclosed by  braces  (see  SHELL  GRAMMAR
              above) exits with a non-zero status.  The shell does not
              exit if the command that fails is part  of  the  command
              list  immediately  following  a  while or until keyword,
              part of the test  following  the  if  or  elif  reserved
              words,  part  of any command executed in a && or || list
              except the command following the final  &&  or  ||,  any
              command  in a pipeline but the last, or if the command's
              return value is being inverted with !.  A trap  on  ERR,
              if set, is executed before the shell exits.  This option
              applies to the shell environment and each subshell envi-
              ronment  separately  (see  COMMAND EXECUTION ENVIRONMENT
              above), and may cause subshells to exit before executing
              all the commands in the subshell.
1
  • 5
    Ahh. I looked for it in the man, but after finding -e in the file tests and no -e under the main arguments I gave up. Nice excerpt. Why is no set required though? :-/
    – pst
    Commented Jun 30, 2011 at 20:43
2

Your script is incorrect, because

egrep "^username" /etc/passwd >/dev/null 
if[ $? -eq 0 ] 
then 
  #echo "doesn't exist" # WRONG
  echo "the USER EXISTS"
fi

exit status 0 - mean - everything is OK, in the case of grep mean "OK, found the string". exit status != 0 mean something is wrong, in the case of grep 1 mean, "not found", 2 mean "can't open input"...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .