On 06/17/2015 04:33 PM, Nick Stoughton wrote: > I was surprised when the following script did NOT exit at the indicated > line: > > set -e > export X=$(false) > # should not reach here
Why not? > The export utility is a special built-in, and according to POSIX XCU 2.8.1 > "Consequences of Shell Errors", special built-ins should exit (with a > diagnostic message) on both variable assignment error and expansion error. But neither occurred. Expansion trivially succeeded (expansion errors are caused by variable expansion under set -u, not by command substitution with non-zero status), and assignment succeeded (you assigned the empty string to $X). And because you did not execute command substitution in isolation, but instead executed 'export', the $? status of the overall line is 0 (that of export's successful assignment of nothing to X), not 1 (the intermediate status of the command substitution). > But every shell I tested behaves the same way (sh, bash, dash, ksh, mksh, > yash and zsh), so I feel I must be missing something. Can someone explain > why the first 2 examples do not exit on the error in the expansion? Because failed $() can only exit the shell when done in a statement with no command name. Your workaround of splitting into: X=$(false) export X is the only way to abort a shell under 'set -e' due to a failed command substitution. And this thread goes to show why we strongly recommend against using 'set -e' - it exists for historical practice, and does NOT generally do what you think it should. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature