Re: exiting noninteractive shells on 'shift 2'

2018-11-09 Thread Eric Blake

On 11/8/18 6:03 PM, Chet Ramey wrote:

On 11/8/18 3:37 PM, Eric Blake wrote:

If I'm reading POSIX correctly, shift is a special built-in utility, and if
'$#' is 0 or 1, then 'shift 2' counts as a utility error that shall exit
the shell, per the table in 2.8.1 Consequences of Shell Errors:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_01



dash gets this right:

$ dash -c 'set 1

shift 2
echo "oops"'

dash: 2: shift: can't shift that many

but bash happily lets 'shift 2' fail with $? set to 1 but continues on with
execution of the rest of the script, even when in POSIX mode:


As you later note:

"If the n operand is invalid or is greater than "$#", this may be
considered a syntax error and a non-interactive shell may exit; if the
shell does not exit in this case, a non-zero exit status shall be returned.
Otherwise, zero shall be returned."

So the bash behavior is not a conformance issue, and allowed by the
standard.


Well, there's STILL a conformance issue - the standard requires that 
unless documented otherwise, any time a command line tool exits with 
non-zero status, that it outputs a message to stderr explaining the 
error.  The page for 'shift' does not document an exception for an exit 
status of 1 being silent, yet bash is completely silent when 'shift 2' 
returns non-zero status.  Producing an error message to stderr would 
call the developer's attention to the bug in their script and the fact 
that bash did not shift out 1 argument, whether or not you also change 
bash to exit the script or continue with execution.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: exiting noninteractive shells on 'shift 2'

2018-11-09 Thread Chet Ramey
On 11/9/18 9:47 AM, Eric Blake wrote:

> Well, there's STILL a conformance issue - the standard requires that unless
> documented otherwise, any time a command line tool exits with non-zero
> status, that it outputs a message to stderr explaining the error.  

Where?

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: exiting noninteractive shells on 'shift 2'

2018-11-09 Thread Eric Blake

On 11/9/18 8:52 AM, Chet Ramey wrote:

On 11/9/18 9:47 AM, Eric Blake wrote:


Well, there's STILL a conformance issue - the standard requires that unless
documented otherwise, any time a command line tool exits with non-zero
status, that it outputs a message to stderr explaining the error.


Where?



http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#shift

"STDERR

The standard error shall be used only for diagnostic messages."

"CONSEQUENCES OF ERRORS

Default."

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html

1.4 Utility Description Defaults:

STDERR

"Default Behavior: When this section is listed as "The standard error 
shall be used only for diagnostic messages.", it means that, unless 
otherwise stated, the diagnostic messages shall be sent to the standard 
error only when the exit status indicates that an error occurred and the 
utility is used as described by this volume of POSIX.1-2017."


CONSEQUENCES OF ERRORS

"The following shall apply to each utility, unless otherwise stated:

If the requested action cannot be performed on an operand 
representing a file, directory, user, process, and so on, the utility 
shall issue a diagnostic message to standard error and continue 
processing the next operand in sequence, but the final exit status shall 
be returned as non-zero.


For a utility that recursively traverses a file hierarchy (such as 
find or chown -R), if the requested action cannot be performed on a file 
or directory encountered in the hierarchy, the utility shall issue a 
diagnostic message to standard error and continue processing the 
remaining files in the hierarchy, but the final exit status shall be 
returned as non-zero.


If the requested action characterized by an option or 
option-argument cannot be performed, the utility shall issue a 
diagnostic message to standard error and the exit status returned shall 
be non-zero.


When an unrecoverable error condition is encountered, the utility 
shall exit with a non-zero exit status.


A diagnostic message shall be written to standard error whenever an 
error condition occurs."


Since 'shift 2' when $# is 1 is an error, and results in non-zero 
status, it should print a diagnostic to stderr.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: exiting noninteractive shells on 'shift 2'

2018-11-09 Thread Chet Ramey
On 11/9/18 11:22 AM, Eric Blake wrote:
> On 11/9/18 8:52 AM, Chet Ramey wrote:
>> On 11/9/18 9:47 AM, Eric Blake wrote:
>>
>>> Well, there's STILL a conformance issue - the standard requires that unless
>>> documented otherwise, any time a command line tool exits with non-zero
>>> status, that it outputs a message to stderr explaining the error.
>>
>> Where?
>>

>     A diagnostic message shall be written to standard error whenever an
> error condition occurs."
> 
> Since 'shift 2' when $# is 1 is an error, and results in non-zero status,
> it should print a diagnostic to stderr.

So maybe the thing to do is to turn on the shift_verbose option in posix
mode.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: exiting noninteractive shells on 'shift 2'

2018-11-09 Thread Eric Blake

On 11/9/18 10:42 AM, Chet Ramey wrote:




     A diagnostic message shall be written to standard error whenever an
error condition occurs."

Since 'shift 2' when $# is 1 is an error, and results in non-zero status,
it should print a diagnostic to stderr.


So maybe the thing to do is to turn on the shift_verbose option in posix
mode.


Cool - I didn't realize we already had a shopt for that. Yes, it sounds 
like in POSIX mode, shift_verbose should be turned on.


On a related note, should turning on POSIX mode also auto-enable xpg_echo?

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: exiting noninteractive shells on 'shift 2'

2018-11-09 Thread Chet Ramey
On 11/9/18 11:46 AM, Eric Blake wrote:
> On 11/9/18 10:42 AM, Chet Ramey wrote:
> 
>>
>>>  A diagnostic message shall be written to standard error whenever an
>>> error condition occurs."
>>>
>>> Since 'shift 2' when $# is 1 is an error, and results in non-zero status,
>>> it should print a diagnostic to stderr.
>>
>> So maybe the thing to do is to turn on the shift_verbose option in posix
>> mode.
> 
> Cool - I didn't realize we already had a shopt for that. Yes, it sounds
> like in POSIX mode, shift_verbose should be turned on.
> 
> On a related note, should turning on POSIX mode also auto-enable xpg_echo?

No. That's just more of a can of worms than I want to deal with. Bash
claims strict conformance with both posix and xpg_echo enabled (that's what
the `strict-posix' configure option does, among other things).

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



[PATCH] initial word completion: fix completion of prefix

2018-11-09 Thread Luca Boccassi
If the user types:

gcfile.c

And positions the cursor of 'f', a programmable completion enabled on
initial word (-I) will fail to run. This is because the parsing gives
priority first to the _minimal programmable completion that does
nothing, and then if that is disabled it gives the next priority to
command completion, unlike what happens when completing a full word,
stopping the initial word completion from working.

To reproduce:

cat > repro<
---

Dear maintainer,

This is the simplest and cleanest solution I could find. I'm happy to
test alternative bug fixes if necessary.
Thanks!

 bashline.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/bashline.c b/bashline.c
index 0d39714f..83ef3fa8 100644
--- a/bashline.c
+++ b/bashline.c
@@ -1580,8 +1580,11 @@ attempt_shell_completion (text, start, end)
   else if (e > s && was_assignment == 0 && have_progcomps)
{
  prog_complete_matches = programmable_completions (n, text, s, e, 
&foundcs);
- /* command completion if programmable completion fails */
- in_command_position = s == start && STREQ (n, text);  /* XXX */
+ /* command completion if programmable completion fails.
+Initial word completion can be done on prefix: gcfile.c -> gcc 
file.c
+when tabbing with cursor on 'f' and needs to have precedence over 
cmd completion. */
+ in_command_position = s == start && (iw_compspec || STREQ (n, text)); 
/* XXX */
+ foundcs = foundcs && !iw_compspec;
}
   /* empty command name following command separator */
   else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0 &&
-- 
2.19.1