I'm trying to create a simple Bash script to check if the website is down and for some reason the "and" operator doesn't work:
#!/usr/bin/env bash
WEBSITE=domain.com
SUBJECT="$WEBSITE DOWN!"
EMAILID="[email protected]"
STATUS=$(curl -sI $WEBSITE | awk '/HTTP\/1.1/ { print $2 }')
STRING=$(curl -s $WEBSITE | grep -o "string_to_search")
VALUE="string_to_search"
if [ $STATUS -ne 200 ] && [[ "$STRING" != "$VALUE" ]]; then
echo "Website: $WEBSITE is down, status code: '$STATUS' - $(date)" | mail -s "$SUBJECT" $EMAILID
fi
The "-a" operator also doesn't work:
if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]
Could you also please advise when to use:
?
This question is related to
bash
if-statement
What you have should work, unless ${STATUS}
is empty. It would probably be better to do:
if ! [ "${STATUS}" -eq 200 ] 2> /dev/null && [ "${STRING}" != "${VALUE}" ]; then
or
if [ "${STATUS}" != 200 ] && [ "${STRING}" != "${VALUE}" ]; then
It's hard to say, since you haven't shown us exactly what is going wrong with your script.
Personal opinion: never use [[
. It suppresses important error messages and is not portable to different shells.
Try this:
if [ $STATUS -ne 200 -a "$STRING" != "$VALUE" ]; then
Quote:
The "-a" operator also doesn't work:
if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]
For a more elaborate explanation: [
and ]
are not Bash reserved words. The if
keyword introduces a conditional to be evaluated by a job (the conditional is true if the job's return value is 0
or false otherwise).
For trivial tests, there is the test
program (man test
).
As some find lines like if test -f filename; then foo bar; fi
, etc. annoying, on most systems you find a program called [
which is in fact only a symlink to the test
program. When test
is called as [
, you have to add ]
as the last positional argument.
So if test -f filename
is basically the same (in terms of processes spawned) as if [ -f filename ]
. In both cases the test
program will be started, and both processes should behave identically.
Here's your mistake: if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]
will parse to if
+ some job, the job being everything except the if
itself. The job is only a simple command (Bash speak for something which results in a single process), which means the first word ([
) is the command and the rest its positional arguments. There are remaining arguments after the first ]
.
Also not, [[
is indeed a Bash keyword, but in this case it's only parsed as a normal command argument, because it's not at the front of the command.
Try this:
if [ ${STATUS} -ne 100 -a "${STRING}" = "${VALUE}" ]
or
if [ ${STATUS} -ne 100 ] && [ "${STRING}" = "${VALUE}" ]
Source: Stackoverflow.com