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

Reply via email to