Reputation: 2040
I have an if statement within a loop. It's set to false initially so I insert a timestamp in a file at the first run of the loop.
I can't seem to get the following to evaluate correctly.
$ConnectionIsCurrently=false
if ! [ $ConnectionIsCurrently ]; then
# changing false to true so this only occurs once.
$ConnectionIsCurrently=true
fi
Here is the full loop:
while [ $i -le $NoOfTests ]; do
ping -c1 -t1 www.google.ie > /dev/null
if [ $? = 0 ]; then
ConTestPASSCount=$((ConTestPASSCount+1))
if ! [ $ConnectionIsCurrently ]; then
printf 'PASSED AT: '
date "+%s"
printf 'PASSED AT: ' >> $directory$LogFile
date "+%s" >> $directory$LogFile
ConnectionIsCurrently=true
fi
echo "PASSCount $ConTestPASSCount"
else
ConTestFAILCount=$((ConTestFAILCount+1))
if [ $ConnectionIsCurrently ]; then
printf 'FAILED AT: '
date "+%s"
printf 'FAILED AT: ' >> $directory$LogFile
date "+%s" >> $directory$LogFile
ConnectionIsCurrently=false
fi
echo "FAILCount $ConTestFAILCount"
fi
sleep 1
Testcount=$((Testcount+1))
i=$((i+1))
done
Upvotes: 0
Views: 43
Reputation: 263467
To summarize:
if
and while
execute a command and branch depending on whether that command succeeds or fails.
false
is a command that produces no output and always fails.
true
is a command that produces no output and always succeeds.
[
is a command that succeeds or fails depending on the evaluation of the expression preceding the closing ]
argument; man test
or info test
for details. With a single argument (which should be enclosed in double quotes) before the ]
, [
succeeds if and only if the argument is non-empty. The [
command is typically built into the shell, but it acts like a command; it's not a special shell syntax.
The shell (sh, bash, ksh, zsh) does not have built-in Boolean types or values. There are several common idioms for using Booleans in shell scripts.
A. Assign a variable the string value true
or false
. Using such a value in an if
statement will do the right thing. (This method is my personal favorite.) Note that the strings true
and false
are the names of commands, not arbitrary strings.
foo=true
if $foo ; then echo OK ; else echo Oops ; fi
B. Assign a variable any arbitrary non-empty value for truthiness, or the empty string (or leave it unset) for falsitude:
foo=yes
if [ "$foo" ] ; then echo OK ; else echo Oops ; fi
foo=""
if [ "$foo" ] ; then echo Oops ; else echo OK ; fi
(The shell treats an unset variable as if it were set to the empty string -- unless you've done set -o nounset
, but that's not usually done in scripts.)
C. Pick two arbitrary strings to represent truth and falsehood, and use them consistently. Use string comparisons to test.
foo=TRUE
if [ "$foo" = TRUE ] ; then echo OK ; else echo Oops ; fi
foo=FALSE
if [ "$foo" = TRUE ] ; then echo Oops ; else echo OK ; fi
All of these methods are potentially error-prone. If you forget a $
or misspell one of your conventional strings, you can get bad results with no warning from the shell; for example with method C, the string True
will silently be treated as a false condition. Languages with strictly behaving Booleans can avoid these problems. Bash is not such a language.
Upvotes: 2
Reputation: 247012
false
and true
are actually commands (and also bash builtins), so you can run them as commands and act on the exit status:
ConnectionIsCurrently=false
if ! $ConnectionIsCurrently; then
# changing false to true so this only occurs once.
ConnectionIsCurrently=true
fi
The [...]
are not required syntax for the if
command: [
is just a regular command whose exit status is used by if
.
Upvotes: 3
Reputation: 781706
The shell doesn't have boolean values, it just operates on strings (or numbers in $(())
). The syntax:
if [ $ConnectionIsCurrently ]
tests whether $ConnectionIsCurrently
is a non-empty string, and "false"
is not empty.
You could use an empty value as falsey, and any non-empty value as truthy.
ConnectionIsCurrently=
if ! [ "$ConnectionIsCurrently" ]; then
ConnectionIsCurrently=true
fi
Note also that you don't put $
before the variable name when you're assigning to it, only when you're reading it. And you should generally quote variables, unless you're sure you want word splitting done. This is especially important when the variable could be empty, as in this case; without the quotes, the [
command doesn't receive any parameter there.
Upvotes: 5