Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0000960 [1003.1(2013)/Issue7+TC1] Shell and Utilities Objection Error 2015-06-18 14:59 2019-06-10 08:54
Reporter eblake View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Closed  
Name Eric Blake
Organization Red Hat
User Reference ebb.export
Section XSH export
Page Number 2373
Line Number 75609
Interp Status Approved
Final Accepted Text See Note: 0002777.
Summary 0000960: export can fail
Description Several special builtins are documented as always having an exit status of 0, even though this is easily proven to be untrue in interactive shells (in non-interactive shells, if the script aborts, it is not possible to observe the exit status of the failed builtin within the script, but only the overall status of the shell). For example:

$ PS1='+ ' bash --posix --norc
+ export 1
bash: export: `1': not a valid identifier
+ echo $?
1
+ readonly -p > /dev/full
bash: readonly: write error: No space left on device
+ echo $?
1
+ set -1
bash: set: -1: invalid option
set: usage: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
+ echo $?
2
+ set >/dev/full
bash: set: write error: No space left on device
+ echo $?
1
+ times >/dev/full
bash: times: write error: No space left on device
+ echo $?
1
+ exit
exit
$

demonstrating that invalid variable names, write() failures during uses of builtins that produce output, and invalid options to set are obvious errors (the standard says that 'export' with no arguments has unspecified behavior, but many shells treat that as printing all currently exported variables, which is another way that could trigger write failure).

If the observed non-zero status could be attributed to a variable assignment error, then it can be argued that the failed variable assignment, rather than the builtin command, caused the non-zero exit status (see section 2.8.1 line 74292, and section 2.9.1 line 74362). It is somewhat ambiguous as to whether 'readonly a=1; export a=2' is an assignment error or a failure of 'export' proper (in part, it depends on whether you consider 'export' to be an assignment context command, per 0000352); but the example above of an invalid variable name is certainly not a failed variable assignment (and in fact, with bash you can prove that under --posix mode, where bash aborts for a failed assignment to a readonly variable but not for an invalid variable name). At any rate, the wording proposed here should be okay (in part because it borrows from existing wording for 'unset').

While at it, I noticed a self-contradiction in the requirements for readonly, which specifies the behavior of 'readonly -p' (which is a use of options but no arguments) then states that with no arguments the behavior is unspecified. Existing shells have inconsistent behavior for 'readonly -p a' (whether it filters the output list to just input names that are readonly, raises an error, or just ignores arguments and blindly prints all readonly variables).
Desired Action At page 2373 line 75609 [XBD export EXIT STATUS], change
Zero.
to
0 All name operands were successfully exported.
>0 At least one name could not be exported.


At page 2375 line 75673 [XBD readonly DESCRIPTION], change
When no arguments are given, the results are unspecified.
to
When arguments are given with the -p option, or when no arguments are given without the -p option, the results are unspecified.


At page 2376 line 75695 [XBD readonly EXIT STATUS], change
Zero.
to
0 All name operands were successfully marked readonly.
>0 At least one name could not be marked readonly, or the -p option was specified and an error occurred.


At page 2383 line 75944 [XBD set EXIT STATUS], change
Zero.
to
0 Successful completion.
>0 An invalid option was specified, or no options and arguments were specified and an error occurred.


At page 2389 line 76171 [XBD times EXIT STATUS], change
Zero.
to
0 Successful completion.
>0 An error occurred.

Tags tc2-2008
Attached Files

- Relationships
related to 0000352Closedajosey 1003.1(2008)/Issue 7 behavior when assignments precede export 
related to 0000882Closed 1003.1(2013)/Issue7+TC1 meaning of "utility syntax error" unclear 

-  Notes
(0002718)
eblake (manager)
2015-06-18 15:08
edited on: 2015-06-18 15:10

Would it be worth also enhancing export's APPLICATION USAGE to warn people about the following common pitfall? (I ask because I spawned this bug in reaction to a thread on the bash list: https://lists.gnu.org/archive/html/bug-bash/2015-06/msg00071.html) [^]

Note that unless X was previously marked readonly, the value of $? after
export X=$(false)
will be 0 (because export successfully set X to the empty string) and that execution continues, even if set -e is in effect. In order to detect command substitution failures, a user must separate the assignment from the export, as in
X=$(false)
export X


(0002721)
eblake (manager)
2015-06-18 17:23

The case of 'set -1' failing arguably falls under the table in 2.8.1 "Utility syntax error (option or operand error)" (line 74290), so my wording tweaks for set may not be quite right. On the other hand, 0000882 removes that wording from the table. Other cases to consider:

$ PS1='+ ' bash --norc --posix
+ exit a
exit
bash: exit: a: numeric argument required
$ echo $?
2
$

which exited bash anyways, but at least picked a non-zero status. On the other hand:

$ PS1='+ ' ksh
+ a=5
+ exit -a
ksh: exit: -a: unknown option
Usage: exit [ options ] [n]
+ echo $?
2
+ false
+ exit a
$ echo $?
0
$

ksh rejects invalid options without exiting; but with non-integer arguments it just silently treated the argument as 0 (rather than trying to do arithmetic interpretation of a potential variable name, or warning about the non-integer argument, or at least preserving the prior $? as if no argument had been given).

Indeed, the specification of exit doesn't say anything about what happens if 'n' is not an integer or is larger than 255 (line 75534); meanwhile, return says behavior is undefined if 'n' is larger than 255, but doesn't deal with non-integral 'n' (line 75758). Contrast that with break (line 75143) which is clear when 'n' is non-integral, or even with eval (line 75393) which went to great lengths to describe that a non-zero exit status is produced in cases where argument errors result in failure without aborting the shell (such as 'eval -n' when there is no -n option supported).

So we may want to visit the exit status sections of all of the builtins when settling on the final wording here.
(0002726)
geoffclare (manager)
2015-06-19 08:19

Regarding this part of the description:

"... specifies the behavior of 'readonly -p' (which is a use of options but no arguments) then states that with no arguments the behavior is unspecified."

There is no problem here - you are mixing up "arguments" and "operands". Options are arguments (as are operands, option-arguments, and the "--" delimiter).

So the page 2375 part of the desired action should be removed.

There is a similar problem with the use of "options and arguments" in the page 2383 change. (It should be just "arguments".)

Finally, the change for export (page 2373) is missing the -p case. It should be:

>0 At least one name could not be exported, or the -p option was specified and an error occurred.
(0002757)
eblake (manager)
2015-07-16 15:16
edited on: 2015-07-16 15:17

return could also use some improvements; at least bash changes $? to an unrelated value when the argument to return is not valid.

$ bash -c 's() { return $1; }; f() { s 3; return x; }; f; echo $?'
bash: line 0: return: x: numeric argument required
2
$ ksh -c 's() { return $1; }; f() { s 3; return x; }; f; echo $?'
0

(0002760)
joerg (reporter)
2015-07-16 15:28
edited on: 2015-07-16 15:35

Bourne Shell regrdless of whether using Solaris version or Schily version:

LC_ALL=C bosh -c 's() { return $1; }; f() { s 3; return x; }; f; echo $?'
bosh: x: bad number
echo $?
1

looks like an error exit via the internal failure() macro

The echo $? inside the -c command is not executed.

(0002777)
eblake (manager)
2015-07-30 17:05
edited on: 2015-08-06 16:14

Interpretation response
------------------------
The standard is unclear on this issue, and no conformance distinction can be made between alternative implementations based on this. This is being referred to the sponsor.

Rationale:
-------------
The standard was unclear whether certain shell special builtins must have exit status of 0, or whether the overall rule for non-zero status after error detection applied. Existing shells have non-zero status after errors.

Notes to the Editor (not part of this interpretation):
-------------------------------------------------------
Make the following changes:

At page 2370 line 75534 [XCU exit EXIT STATUS], change
The exit status shall be n, if specified.
to
The exit status shall be n, if specified, except that the behavior is unspecified if n is not an unsigned decimal integer or is greater than 255.


At page 2371 line 75552 [XCU exit RATIONALE], add a new paragraph:
The behavior of exit when given an invalid argument or unknown option is unspecified, because of differing practices in the various historical implementations. A value larger than 255 might be truncated by the shell, and be unavailable even to a parent process that uses waitid() to get the full exit value. It is recommended that implementations that detect any usage error should cause a non-zero exit status (or, if the shell is interactive and the error does not cause the shell to abort, store a non-zero value in $?), but even this was not done historically in all shells.


At page 2373 line 75609 [XCU export EXIT STATUS], change
Zero.
to
0 All name operands were successfully exported.
>0 At least one name could not be exported, or the -p option was specified and an error occurred.


At page 2373 line 75613 [XCU export APPLICATION USAGE], change
None.
to
Note that, unless X was previously marked readonly, the value of $? after
export X=$(false)
will be 0 (because export successfully set X to the empty string) and that execution continues, even if set -e is in effect. In order to detect command substitution failures, a user must separate the assignment from the export, as in
X=$(false)
export X


At page 2376 line 75695 [XCU readonly EXIT STATUS], change
Zero.
to
0 All name operands were successfully marked readonly.
>0 At least one name could not be marked readonly, or the -p option was specified and an error occurred.


At page 2378 line 25759 [XCU return EXIT STATUS], change
If the value of n is greater than 255, the results are undefined.
to
If n is not an unsigned integer, or is greater than 255, the results are unspecified.


At page 2383 line 75944 [XCU set EXIT STATUS], change
Zero.
to
0 Successful completion.
>0 An invalid option was specified, or an error occurred.


At page 2389 line 76171 [XCU times EXIT STATUS], change
Zero.
to
0 Successful completion.
>0 An error occurred.


(0002784)
ajosey (manager)
2015-08-07 18:39

Interpretation Proposed: 7 Aug 2015
(0002817)
ajosey (manager)
2015-09-07 11:33

Interpretation approved: 7 Sep 2015

- Issue History
Date Modified Username Field Change
2015-06-18 14:59 eblake New Issue
2015-06-18 14:59 eblake Name => Eric Blake
2015-06-18 14:59 eblake Organization => Red Hat
2015-06-18 14:59 eblake User Reference => ebb.export
2015-06-18 14:59 eblake Section => XSH export
2015-06-18 14:59 eblake Page Number => 2373
2015-06-18 14:59 eblake Line Number => 75609
2015-06-18 14:59 eblake Interp Status => ---
2015-06-18 15:04 eblake Description Updated
2015-06-18 15:04 eblake Relationship added related to 0000352
2015-06-18 15:08 eblake Note Added: 0002718
2015-06-18 15:10 eblake Note Edited: 0002718
2015-06-18 17:23 eblake Note Added: 0002721
2015-06-18 17:23 eblake Relationship added related to 0000882
2015-06-19 08:19 geoffclare Note Added: 0002726
2015-07-16 15:16 eblake Note Added: 0002757
2015-07-16 15:17 eblake Note Edited: 0002757
2015-07-16 15:28 joerg Note Added: 0002760
2015-07-16 15:29 joerg Note Edited: 0002760
2015-07-16 15:35 joerg Note Edited: 0002760
2015-07-30 17:05 eblake Note Added: 0002777
2015-07-31 14:51 eblake Note Edited: 0002777
2015-08-06 16:03 eblake Note Edited: 0002777
2015-08-06 16:06 eblake Note Edited: 0002777
2015-08-06 16:12 eblake Note Edited: 0002777
2015-08-06 16:14 eblake Note Edited: 0002777
2015-08-06 16:15 Don Cragun Interp Status --- => Pending
2015-08-06 16:15 Don Cragun Final Accepted Text => See Note: 0002777.
2015-08-06 16:15 Don Cragun Status New => Interpretation Required
2015-08-06 16:15 Don Cragun Resolution Open => Accepted As Marked
2015-08-06 16:15 Don Cragun Tag Attached: tc2-2008
2015-08-07 18:39 ajosey Interp Status Pending => Proposed
2015-08-07 18:39 ajosey Note Added: 0002784
2015-09-07 11:33 ajosey Interp Status Proposed => Approved
2015-09-07 11:33 ajosey Note Added: 0002817
2019-06-10 08:54 agadmin Status Interpretation Required => Closed


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker