Re: Improving xtrace output from subshells

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 27/04/2019 15:05, Vadim Zeitlin wrote:
On Sat, 27 Apr 2019 01:14:29 +0100 Harald van Dijk <harald@xxxxxxxxxxx> wrote:

HvD> I don't believe there is any requirement for your expectation and
HvD> several other shells share this behaviour, but agreed that it would be a
HvD> nice improvement to avoid this.

  Yes, this is certainly just an expectation and not something guaranteed by
POSIX, but it looks like a very reasonable expectation to me. And, speaking
of the other shells, all of the ones I tested (bash, ksh, zsh) do keep the
lines together.

bosh and yash behave the same as dash.

HvD> Please keep in mind that even without this, you would not have
HvD> deterministic output. The commands in a pipeline could be output in any
HvD> order, even if each command would be output on its own line.

  In theory, it seems like you're right and it should be possible, but in
practice it just doesn't seem to ever happen, i.e. the output is always in
the same left-to-right order. Maybe there is something that implicitly
serializing the output from the pipeline components either in the shell or
in the kernel? I admit I haven't dived into this deep enough to really find
out, the fact that the order remains always the same in practice is good
enough for me.

It seems to mostly work that way in bash, and I have no dug into the reason for that either. You tested ksh and zsh as well. In ksh and zsh, I do commonly see variations in the order in which the lines are printed, and with patched dash, I see the same variations.

Rarely, I see out-of-order prints even in bash, so it does seem like it's just a coincidence as a result of the way of bash is written, not something that bash actively attempts to guarantee. Try it:

  c=0
  while :
  do
    xtrace=$(bash -o posix -xc ': a | : b' 2>&1)
    case $xtrace in
    *a*b*) : $((c+=1)) ;;
    *)     echo $c
           echo "$xtrace"
           break ;;
    esac
  done

It takes hundreds or sometimes even thousands of runs, but eventually, I do see + : b followed by + : a.

HvD> As a proof of concept that should clearly not be committed in its
HvD> current form, please see the attached patch.

  Thanks, this is indeed much simpler than what I had in mind and I can
confirm that it does work.

  What prevents this patch from being applied in the current form exactly?

I removed a #ifdef FLUSHERR which suggests to me this is supposed to be optional, not unconditional.

The macro OUTBUFSIZ should be renamed if it is no longer just the size of the "output" buffer.

I only touched the case where USE_GLIBC_STDIO is undefined. (That said, the case where USE_GLIBC_STDIO is defined is already broken, so this may be okay.)

It wastes memory: the code should be re-worked so that output and preverrout share the same buffer, given that there can never be pending output for one when the other is being written to. (This may apply to errout as well, if someone wants to enable buffering for that.)

Cheers,
Harald van Dijk



[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux