Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Debian zsh bug triage



On Mon, Dec 29, 2008 at 09:46:07PM +0100, Richard Hartmann wrote:
[...]
> 2) Unexpected behaviour when stopping a job in a command chain[3]
> 
> Consider this:
> 
> echo one && sleep 10 && echo two
> 
> When stopping `sleep 10`, `echo two` will never be executed, no matter in
> what way you revive `sleep 10`. That is OK as backgrounding `sleep 10`
> will set $? to 20. Yet, with
> 
> echo one ; sleep 10 ; echo two
> 
> the same thing happens. As Bart pointed out[4]:

I don't observe that with 4.3.9-dev-1-cvs1210

And I can see all the shells behaving the same. Am I missing
something again?

> 
> > Given "one && two && three", if "two" stops, the shell has three choices:
> > (1) pretend the command was "{ one && two && three }" and suspend the
> >     entire sublist; or
> > (2) pretend that "two" has returned a status and continue the junction; or

Well, it does return a status, but it also leaves a job stopped
in background.

> > (3) stop the entire shell until "two" is resumed.
> 
> > Choice (1) is undesirable because it subverts the user's intent (if he
> > meant there to be braces, he should have typed them)
> and it puts "three"
> > into a separate process when it might better have been run in the current
> > shell.  Choice (3) is impossible in an interactive shell.  That leaves
> > (2), which is what zsh does, using the signal number as the status.
> 
> Personally, I think 1) would meet most users' expectations, but any of
> the three are OK. Not executing the third command at all is not, imo. Of
> course, if the third command is a rm, mv or some other potentially
> destructive command, it's best to err on the save side, so I can see why
> that was done. If that is a design decission, I will accept that and
> close the bug accordingly. But keep in mind that 1) would be a save
> solution, as well ;)
[...]


When one runs:

cmd1; cmd2

he may intend that to be a little script of two commands.

If one expects <Ctrl-C> to terminate that little script (which zsh,
ksh, pdksh, ash do), one may expect (1) above as well, that is
<Ctrl-Z> to stop that little script.

On the other end, 2 makes even more sense because you'd expect

cmd1; cmd2
to be the same as
cmd1
cmd2

And according to SUSv4, those are two jobs.

According to SUSv4, a job is a shell pipeline. And:

SUSv4> pipeline         :      pipe_sequence
SUSv4>                  | Bang pipe_sequence
SUSv4>                  ;
SUSv4> pipe_sequence    :                             command
SUSv4>                  | pipe_sequence '|' linebreak command
SUSv4>                  ;
SUSv4> command          : simple_command
SUSv4>                  | compound_command
SUSv4>                  | compound_command redirect_list
SUSv4>                  | function_definition

So, in the case of { cmd1; cmd2; }, we've got one job, so one
would expect <Ctrl-Z> to stop the whole job.

But then, in "cmd1; cmd2", according to SUSv4 again, <Ctrl-C>
should only terminate cmd1 as bash does and run cmd2... so
there's a consistency problem here.

-- 
Stéphane



Messages sorted by: Reverse Date, Date, Thread, Author