⇤ ← Revision 1 as of 2010-08-28 02:11:15
Size: 1290
Comment: Answers, just in case.
|
Size: 1657
Comment: bash 4.1 changed the answer to exercise 2
|
Deletions are marked like this. | Additions are marked like this. |
Line 25: | Line 25: |
'''However''', this behavior changed in bash 4.1. Exercise 2 works only in bash 4.0 and earlier! In bash 4.1, `((...))` qualifies for `set -e` abortion, and this exercise will print nothing, the same as Exercise 1. This reinforces my point about how unreliable `set -e` is. You can't even count on it to behave consistently across point-releases of a shell. |
Exercise 1: why doesn't this example print anything?
According to the manual, set -e exits "if a simple command (see SHELL GRAMMAR above) exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in a if statement, part of an && or || list, or if the command's return value is being inverted via !".
The let command is a simple command, and it doesn't qualify for any of the exceptions in the above list. Moreover, help let tells us "If the last ARG evaluates to 0, let returns 1; 0 is returned otherwise." i++ evaluates to 0, so let i++ returns 1 and trips the set -e. The script aborts. Because we added 1 to a variable.
Exercise 2: why does this one appear to work?
((...)) does not qualify as a simple command according to the shell grammar. So it is not eligible to trigger a set -e abort, even though it still returns 1 in this particular instance (because i++ evaluates to 0 while setting i to 1, and because 0 is considered false in a math context).
However, this behavior changed in bash 4.1. Exercise 2 works only in bash 4.0 and earlier! In bash 4.1, ((...)) qualifies for set -e abortion, and this exercise will print nothing, the same as Exercise 1.
This reinforces my point about how unreliable set -e is. You can't even count on it to behave consistently across point-releases of a shell.