I'm fairly new to scripting and I want to learn how to check the values of $? to check whether the a grep command was successful, If the grep command is not successful, then to echo a message which includes the values of $name. How can I achieve this, I'm aware that I can use an If statement and a special shell variable but I don't know the proper syntax. I gave it a try in the code below.

         if [ "$name" =  "" ]
         then  echo -n "Name 'DBS' is not in directory"
            read name

grep -i $name mike ~admin/dbs/email
grep -i goodman ~admin/dbs/passwd
  • show an example of what you're trying to do with grep. from what you've shown so far, grep is irrelevant.
    – cas
    Dec 2, 2015 at 5:35
  • I updated the script @cas
    – Katz
    Dec 2, 2015 at 5:40
  • Re: your edit adding the grep -i ... examples. I am confused, as the first command looks for the pattern in $name in the files mike and ~admin/dbs/email, then the second one looks for goodman, so I'm thinking the first line probably doesn't do what you want it to. Can you elaborate on exactly what you're trying to search with those grep statements? And then, which grep statement are you interested in the status ($?) of? Dec 2, 2015 at 6:32

2 Answers 2


Here's some fairly typical syntax. It could do with some more error checking, but within the scope of what you're looking to do, I believe this will help you on to the right track:



if [ -z "$1" ]; then
    echo Usage: $0 name 1>&2
    exit 2

if grep -q "$1" $file ; then
    echo "$file" contains $1
    echo "$file" doesn\'t contain $1


  • The first test (if [ -z "$1" ]; then ...) is true if $1 (first commandline argument) is an empty string (or was not provided).
  • The Usage: line is output to stderr with 1>&2
  • The output of grep itself is hidden (except for error output, which you'd probably want to see), since in this case we only want to know if it was successful (match found) or not.
    • grep has a parameter -q that silences all output, which is the better choice here, but not all commands have a "quiet" switch, In those cases, you can use >/dev/null instead, as in my example below.

Specific example with $?

You specifically asked for an example with $?. Instead of the above if grep ... construct, we could indeed split that into separate statements:

# grep -q "$1" $file would work just as well, here (better, maybe!):
grep "$1" $file >/dev/null

if [ $? -eq 0 ]; then
    echo "$file" contains $1
    echo "$file" doesn\'t contain $1

It's important to note that testing $? must happen immediately after the command in question, as any other commands (excluding some shell builtins) will cause the value to be overwritten.

What is $?

$? is simply the exit code of the last process (command) executed by the shell. By convention, a 0 exit code is success (although, as with most conventions, there are exceptions). Higher exit codes can have various meanings specific to the application, but usually non-zero means some kind of abnormal exit. Consult the documentation of the command for more information.

Further reading


  • try grep -q rather than grep > /dev/null
    – cas
    Dec 2, 2015 at 5:38
  • @cas Indeed, that would be a better practice. Initially I had thought >/dev/null would provide for a more general example, but I agree; no point teaching over-generalized habits when -q will do. I'll work it in. Dec 2, 2015 at 5:50

Another quick way, that avoids if-statements as well as $?, but is pretty nice and short (oneliner!), in my opinion, would be:

grep -q $name $file || echo "$name not found."

if you want to echo if grep returns 0:

grep -q $name $file && echo "$name found."

and as an if-else-statemet:

grep -q $name $file && echo "$name found." || echo "$name not found."

You must log in to answer this question.

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