a=1
b=1
if ! grep -q -F -- 'too many requests' *.htm* && [ "$a" = "$b" ]; then
echo error >&2
fi
This uses the negated exit status of grep
and the result of comparing $a
and $b
for string equality (use [
's -eq
for integer evaluation of equality). If both are true (the string is not found in any file matching *.htm*
and the two variables are identical), then the echo
is executed, outputting the string error
to the standard error stream.
Note the use of single =
with spaces around it. The =
(or -eq
) operator is an argument to the [
(test
) utility and not intrinsically tied to the if
keyword.
The options -q
and -F
to the grep
utility cause the utility to be quiet and to exit as soon as a match is found (-q
) and to treat the given pattern as a text string rather than as a regular expression (-F
).
Your examples use a while
loop, which should be an if
statement. If you want to handle each file separately, then use a for
loop:
for name in *.htm*; do
if ! grep -q -F -- 'too many requests' "$name" && [ "$a" = "$b" ]
then
printf 'error for "%s"\n' "$name" >&2
fi
done
You don't have to save the output of grep
if you only want to test whether a pattern matches in a file or set of files. You may instead use grep -q
and react to the exit status of the utility, as shown above.
In your first code snippet, you use an arithmetic evaluation, (( $a -eq $b ))
. This could be better written as (( a == b ))
, which evaluates to a result that an if
statement could use as a boolean. The -eq
operator is specific to the [
utility and not valid in (( ... ))
.
In the second code snippet, you use $a==$b
. This would evaluate into a string, 1==1
, which the shell would try to use as a command.
In the third code snippet, you use "$a" -eq "$b"
within [[ ... ]]
, which correctly performs an integer equality test between $a
and $b
. This does not work as expected due to the grep
command and the way you don't negate its exit status (and the fact that you use a while
loop rather than an if
statement).
Within [ ... ]
, =
tests for string equality and -eq
tests for integer equality. Technically, ==
is not a valid operator for [ ... ]
tests, but bash
supports it. The bash
shell does shell pattern matching within its special [[ ... ]]
syntax when using ==
, as in
[[ $name == *.txt ]] && echo 'The name matches *.txt'