cc: [email protected]
Subject: Re: [ast-users] post-loop output question
--------
> Hello,
>
> I noticed that I get different values for a variable at the end of a loop
> when I
> follow the close of the loop with a pipe to tee(1) instead of a redirect to
> a f
> ile. Specifically, if I increment values in the loop and then redirect the
> outp
> ut of the loop, the value after processing is what had been incremented
> during t
> he loop. Conversely, if I pipe to tee instead of redirecting then I get the
> pre
> -loop value of the variable instead of the value that incremented in the
> loop.
> In both cases the value increments, it's just what I get after the loop has
> fini
> shed that changes depending on how I handle the output.
>
> There is probably a logical explanation for this, and that is what I am
> seeking
> with his post to the list. It doesn't make any difference what file
> descriptor
> I read from. Below is some sample code that exhibits the behavior that I
> don't
> understand. Change line 16 from "| tee -a logfile.txt" to "> logfile.txt" to
> el
> icit the behavior that I was expecting.
>
> 1 errors=100
> 2 tmpfile=$( mktemp '/tmp/x.XXXXX' )
> 3
>
> 4 for ((i=0;i<10;i++))
> 5 do print 'a'
> 6 done > $tmpfile
> 7
>
> 8 print "(pre-loop) errors: $errors"
> 9
>
> 10 exec 3<"${tmpfile}"
> 11 while read -r -- tok1 tok2 discard
> 12 do
> 13 if [[ -z $tok1 ]] || [[ -z $tok2 ]]
> 14 then
> 15 ((errors++))
> 16 fi
> 17 print "(in-loop) errors: $errors"
> 18 done < "${tmpfile}" | tee -a logfile.txt
> 19 exec 3<&-
> 20
>
> 21 print "(post-loop) errors: $errors"
> 22 whence -v ksh
> 23 whence -v tee
> 24 print ${.sh.version}
>
> Output from the above:
>
> (pre-loop) errors: 100
> (in-loop) errors: 101
> (in-loop) errors: 102
> (in-loop) errors: 103
> (in-loop) errors: 104
> (in-loop) errors: 105
> (in-loop) errors: 106
> (in-loop) errors: 107
> (in-loop) errors: 108
> (in-loop) errors: 109
> (in-loop) errors: 110
> (post-loop) errors: 100
> ksh is a tracked alias for /opt/ast/bin/ksh
> tee is a tracked alias for /opt/ast/bin/tee
> Version M 1993-12-28 s+
>
>
> Thanks in advance for helping me understand this.
>
> --
> Rick Robino
The results are correct. When you do run a pipeline, all but the last is
run in a separate process. Thus, errors is only being incremented in
the process that runs the loop, not the one that does the tee.
It can be done without creating a subshell for the loop, but it is
not obvious. Here is how. Change the done line to
done < "${tmpfile}" {n}> >(tee -a logfile.txt <&1)
What this does it to create file descriptor $n which is one end of a process
the is a tee that reads from standard input.
David Korn
[email protected]
_______________________________________________
ast-users mailing list
[email protected]
https://mailman.research.att.com/mailman/listinfo/ast-users