0

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.

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

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 '15 at 5:35
  • I updated the script @cas – Katz Dec 2 '15 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? – type_outcast Dec 2 '15 at 6:32
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:

#!/bin/bash

file=/etc/hosts

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

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

Notes

  • 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
else
    echo "$file" doesn\'t contain $1
fi

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

test(1)

  • try grep -q rather than grep > /dev/null – cas Dec 2 '15 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. – type_outcast Dec 2 '15 at 5:50
0

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."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.