I see the same behaviour for below loop as the loop with
while [ 1 ]. Why is that so?
while [ 0 ]; do echo "hello" done
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.Sign up to join this community
Single square brackets in the shell is a synonym for
test (either the separate command or the shell built-in), so
[ 0 ] means the same thing as
test is for doing comparisons and testing the attributes of files, as you can read about in its manpage. When it isn't given an expression that looks like a comparison, file test, or one of the other operations it can do, it will instead test if the argument is present and a non-empty string. Neither
1 are really appropriate inputs for test, and as non-empty strings test simply succeeds and your while loop loops forever.
You may want to try instead
while false; do echo "hello" done
true. Or maybe what you want is to use
while (( 0 )); do echo "hello" done
Which will behave like most languages, where 0 means failure/false and 1 means success/true.
The value 0 here is not acting as a numeric constant, but as a character string. These tests are all equivalent in their effect of producing a successful termination status:
[ A ] [ "XYZ" ] [ 0 ]
these produce a failed termination status:
[ ] [ "" ]
there is a non-blank argument, which evaluates to logical true. This allows you to do things like:
if [ $UNDER_NUCLEAR_ATTACK ] ; then launch-missiles -a $DRY_RUN # $DRY_RUN set to "-n" during testing fi
UNDER_NUCLEAR_ATTACK is set to any non-blank value to indicate true, or is unset or empty to indicate false.
We can apply the
! operator to reverse the logic:
[ ! a ] # fails: a is nonblank so true; and not true is false. [ ! ] # succeeds: blank is false, not blank is true.
To evaluate a numeric condition, you have to use numeric test operators:
while [ $A -gt $B ] ; do ...
B contain strings that look like decimal integers, they are compared like numbers, and if
A is greater than
B, the loop executes. So suppose that
UNDER_NUCLEAR_ATTACK is not a string-type boolean that is blank or nonblank, but actually a numeric boolean that is either
0 (false) or some other value (true). In that case, we would write the test like this:
if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...
An if/then construct tests whether the exit status of a list of commands is 0 (since 0 means "success" by UNIX convention), and if so, executes one or more commands.
In short, you're returning a test result of zero.