On Wed, Mar 22, 2017 at 10:12:37AM +0100, Jean Delvare wrote:
> Hi Thorsten,
> 
> One of our customers recently asked us about the different behavior of
> constructs involving pipes in ksh scripts. I explained to them that
> mksh spawns a sub-shell for the right hand side of each pipe, and
> therefore whatever happens on that side of the pipe has no effect on
> the main shell.
> 
> While I believe this is a perfectly sane implementation (and as a
> matter of fact, bash and dash behave the same, at least by default), I
> would like to make suggestions to the customer on how they can modify
> their code so that it keeps working.
> 
> With bash, I would have a number of ideas. For example, they could set
> option "lastpipe", which causes the last element of a pipe to be run in
> the main shell, instead of the first. Or they could use process
> substitution (the <() or >() syntax) to explicitly decide which part
> goes in a sub-shell. But it doesn't seem mksh implements any of these?
> 
> One approach which works in all shells is to use temporary files
> instead of pipes, however it could lower the performance of the
> scripts, so I consider it a last resort solution.
> 
> Concretely, the customer's code looks like this:
> 
> command | while read line
> do
>       if <condition>
>       then
>               exit
>       fi
>       process $line
> done
> 
> ... more stuff ...
> 
> The "exit" doesn't work in mksh as it ends the sub-shell, not the main
> shell. One thing that would work in this case is exiting the sub-shell
> with a specific error code, and checking for that code afterward:
> 
> command | while read line
> do
>       if <condition>
>       then
>               ex
> it 42
>       fi
>       process $line
> done
> 
> if [ $? -eq 42 ]
> then
>       exit
> fi
> 
> ... more stuff ...
> 
> I was wondering if there is any other trick you can suggest that would work 
> in mksh?

Just to be mentioned, I can mksh change in such a way that without job control
I can do

   ~/rpmbuild/BUILD/mksh> ./mksh -c 'echo xxx | read yyy; echo $yyy'
   xxx

that is it does work similar to the lastpipe shell option of the bash
I had initiated now 7 years back. The trick is to avouid forking the
last element in a pipe chain.

Don't know if this could help.

Werner

-- 
  "Having a smoking section in a restaurant is like having
          a peeing section in a swimming pool." -- Edward Burr

Attachment: signature.asc
Description: PGP signature

Reply via email to