10

I started learning Bash a couple of days ago.

I'm trying to obtain an exit status of grep expression into a variable like this:

check=grep -ci 'text' file.sh

and the output that I got is

No command '-ic' found

Should I do it with a pipe command?

  • 6
    For exit status you can examine $? right after command is finished. – coffeMug Jul 7 '16 at 8:16
  • and you can examine the PIPESTATUS array if you want the status of one of the commands in a pipeline. – cas Jul 7 '16 at 11:29
20

The shell stores the exit value of most recently executed command in the variable ?. You can assign its value to one of your own variables like this:

grep -i 'PATTERN' file
check=$?

If you want to act on this value, you may either use your check variable:

if [ "$check" -eq 0 ]; then
    # do things for success
else
    # do other things for failure
fi

or you could skip using a separate variable and having to inspect $? all together:

if grep -q -i 'pattern' file; then
  # do things (pattern was found)
else
  # do other things (pattern was not found)
fi

or, if you just want to "do things" when the pattern is not found:

if ! grep -q -i 'pattern' file; then
  # do things (pattern was not found)
fi

Saving $? into another variable is only ever needed if you need to use it later, when the value in $? has been overwritten, as in

mkdir "$dir"
err=$?

if [ "$err" -ne 0 ] && [ ! -d "$dir" ]; then
    printf 'Error creating %s (error code %d)\n' "$dir" "$err" >&2
    exit "$err"
fi

In the above code snippet, $? will be overwritten by the result of the [ "$err" -ne 0 ] && [ ! -d "$dir" ] test. Saving it here is really only necessary if we need to display it and use it with exit.

2

Your question is unclear but based on the code you’ve submitted, it looks like you want the variable check to store the exit status of the grep command. The way to do this is to run

grep -ci 'text' file.sh
check=$?

When running a command from a shell, its exit status is made available through the special shell parameter, $?.

This is documented by POSIX (the standard for Unix-like operating systems) in its specification for the shell and the Bash implementation is documented under Special Parameters.

Since you’re a new learner, I’d strongly recommend that you start with a good book and/or online tutorial to get the basics. Recommendations of external resources are discouraged on Stack Exchange sites but I’d suggest Lhunath and GreyCat’s Bash Guide.

2

You've told bash to set the variable check=grep in the environment it passes to the command

-ci 'text' file.sh

but ci does not exist.

I believe you meant to enclose that command in back-ticks, or in parentheses preceded by a dollar sign, either of which would assign the count of how many lines 'text' was found on (case insensitively) in the file:

check=`grep -ci 'text' file.sh`

check=$(grep -ci 'text' file.sh)

Now $check should be 0 if no matches, or positive if there were any matches.

1

Confused why using -c when checking the output? It's used to check how many times something is matched - not if it's successful or not.

   -c, --count
          Suppress normal output; instead print a count of matching  lines
          for  each  input  file.  With the -v, --invert-match option (see
          below), count non-matching lines.  (-c is specified by POSIX.)

but in this example

check="$(grep --silent -i 'text' file.sh; echo $?)"

It doesn't output anything except a exit code, which is then echoed. This is the output that the variable check uses. I also prefer it because it's a single line.

You can replace --silent with -q. I use it since you're not interested in the grep output, just whether it worked or not.

   -q, --quiet, --silent
          Quiet;  do  not  write  anything  to  standard   output.    Exit
          immediately  with  zero status if any match is found, even if an
          error was detected.  Also see the -s  or  --no-messages  option.
          (-q is specified by POSIX.)

$ check=$(echo test | grep -qi test; echo $?) # check variable is now set
$ echo $check
0
$ check=$(echo null | grep -qi test; echo $?)
$ echo $check
1
0

The correct way to assign the output of grep command to a variable is as @monty-harder mentioned:

check=`grep -ci 'text' file.sh`
check=$(grep -ci 'text' file.sh)

Though to assign the exit status of this command to a variable you have to use the shell parameter $? right after executing the command as shown below:

grep -ci 'text' file.sh
check=$?
echo $check

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.