How do I use a file grep comparison inside a bash if/else statement?
Asked Answered
H

5

154

When our server comes up we need to check a file to see how the server is configured.

We want to search for the following string inside our /etc/aws/hosts.conf file:

MYSQL_ROLE=master

Then, we want to test whether that string exists and use an if/else statement to run one of two options depending on whether the string exists or not.

What is the BASH syntax for the if statement?

if [ ????? ]; then
  #do one thing
else
  #do another thing
fi
Handmedown answered 19/3, 2010 at 21:6 Comment(0)
F
225

From grep --help, but also see man grep:

Exit status is 0 if any line was selected, 1 otherwise; if any error occurs and -q was not given, the exit status is 2.

if grep --quiet MYSQL_ROLE=master /etc/aws/hosts.conf; then
  echo exists
else
  echo not found
fi

You may want to use a more specific regex, such as ^MYSQL_ROLE=master$, to avoid that string in comments, names that merely start with "master", etc.

This works because the if takes a command and runs it, and uses the return value of that command to decide how to proceed, with zero meaning true and non-zero meaning false—the same as how other return codes are interpreted by the shell, and the opposite of a language like C.

Feola answered 19/3, 2010 at 21:10 Comment(3)
> with zero meaning true and non-zero meaning false—the same as how other return codes are interpreted by the shell, and the opposite of a language like C. but why the opposite....?Theoretics
Because a zero is typically interpreted as "no error", while anything else means "some error". If assumes we want to know if the command completed successfully.Herodias
Gets an upvote (and applause) for using the --quiet arg instead of -q in the example. Long-args are so much more readable and self document the intention really clearly.Dingy
A
38

if takes a command and checks its return value. [ is just a command.

if grep -q ...
then
  ....
else
  ....
fi
Alcorn answered 19/3, 2010 at 21:9 Comment(0)
W
27

Note that, for PIPE being any command or sequence of commands, then:

if PIPE ; then
  # do one thing if PIPE returned with zero status ($?=0)
else 
  # do another thing if PIPE returned with non-zero status ($?!=0), e.g. error
fi 

For the record, [ expr ] is a shell builtin shorthand for test expr.

Since grep returns with status 0 in case of a match, and non-zero status in case of no matches, you can use:

if grep -lq '^MYSQL_ROLE=master' ; then 
  # do one thing 
else 
  # do another thing
fi 

Note the use of -l which only cares about the file having at least one match (so that grep returns as soon as it finds one match, without needlessly continuing to parse the input file.)

on some platforms [ expr ] is not a builtin, but an actual executable /bin/[ (whose last argument will be ]), which is why [ expr ] should contain blanks around the square brackets, and why it must be followed by one of the command list separators (;, &&, ||, |, &, newline)

Wiley answered 20/3, 2010 at 17:11 Comment(1)
-l is redundant, grep returns immediately upon finding any match with -qMonocoque
E
4

just use bash

while read -r line
do
  case "$line" in
    *MYSQL_ROLE=master*)
       echo "do your stuff";;
    *) echo "doesn't exist";;      
  esac
done <"/etc/aws/hosts.conf"
Enthusiasm answered 20/3, 2010 at 0:40 Comment(0)
U
1

Below code sample should work:

(echo "hello there" | grep -q "AAA") && [ $? -eq 0 ] && echo "hi" || echo "bye"
Uveitis answered 21/9, 2021 at 14:44 Comment(1)
$? is not needed here : (echo "hello there" | grep -q "AAA") && echo "hi" || echo "bye"Milli

© 2022 - 2024 — McMap. All rights reserved.