On Fri, Sep 11, 2015 at 03:10:13PM +0200, Jean Delvare wrote: > Dear mksh developers, > > A customer of ours is migrating from ksh-93 to mksh. They reported the > following difference in behavior: > > ksh-93: > $ echo X | read A > $ echo $A > X > > mksh: > $ echo X | read A > $ echo $A > > So mksh behaves the same as for example bash, in that changes to the > environment of the right side of a pipe aren't reflected into the main > process. That difference breaks the customer's scripts. > > I would like to ask if this is: > > 1* A deliberate design decision, and this will never change. > > 2* A bug, mksh should behave the same as ksh-93 in this respect. > > 3* Something that was not discussed so far, so status is unknown. > > Additionally, unless answer is 2 above, I would be grateful if you could > suggest an alternative way to achieve the same with mksh. I know how I > would do it with bash, but I don't know what mksh is capable of.
Yes, indeed only orignal ksh and zsh can do ksh93 -c 'echo xxx | read A; echo $A' xxx zsh -c 'echo xxx | read A; echo $A' xxx the mksh can use co-processes as ksh can do ksh93 -c 'echo xxx |& read -p A; echo $A' xxx mksh -c 'echo xxx |& read -p A; echo $A' xxx but not bash nor zsh. A long time ago I had written a small patch fo bash which now seems to be upstream but for bash this is disabled by default. To use it the job control has to be disabled as well as the lastpipee shell option has to be enabled: bash -c 'shopt -s lastpipe; echo xxx | read A ; echo $A' xxx bash -c 'echo $BASH_VERSION' 4.2.46(1)-release Btw: this behaviour of the mksh is docmented in the manual page of mksh: CAVEATS mksh only supports the Unicode BMP (Basic Multilingual Plane). mksh has a different scope model from AT&T UNIX ksh, which leads to subtile differences in semantics for identical builtins. This can cause issues with a nameref to suddenly point to a local variable by accident; fixing this is hard. The parts of a pipeline, like below, are executed in subshells. Thus, variable assignments inside them are not visible in the surrounding execution environment. Use co-processes instead. foo | bar | read baz # will not change $baz foo | bar |& read -p baz # will, however, do so mksh provides a consistent set of 32-bit integer arithmetics, both signed and unsigned, with defined wraparound and sign of the result of a modulo operation, even (defying POSIX) on 64-bit systems. If you require 64-bit integer arithmetics, use lksh (legacy mksh) instead, but be aware that, in POSIX, it's legal for the OS to make print $((2147483647 + 1)) delete all files on your system, as it's Undefined Behaviour. The question rises, if it would be possible to a) let the last pipe of the mksh not be a subshell and/or use shared memory area to make new or changed shell variables and of the sub shell visible to the main shell. Werner -- "Having a smoking section in a restaurant is like having a peeing section in a swimming pool." -- Edward Burr
signature.asc
Description: Digital signature