Jan Palus dixit:

[ note from IRC, this is on PLD Linux ]

>project -- just made an observation in my Linux distribution of choice
>which has mksh as /bin/sh.

\o/
 |
/ \

>1. Looking at the expression in a simplified form:
>
>OUT=$( ((echo foo; echo $? 1>&3) | :) 3>&1 ) && echo "$OUT"
>
>isn't it supposed to echo only 0?

Yes. It does when you do…
 OUT=$( ( (echo foo; echo $? 1>&3) | :) 3>&1 ) && echo "$OUT"

>Both mksh R51 and R52 echo foo and 0,

This is a different bug in each. mksh R50 (which I have at
hand right now) parses it like so…

tg@herc:~ $ foo() {
> OUT=$( ((echo foo; echo $? 1>&3) | :) 3>&1 ) && echo "$OUT"
> }
tg@herc:~ $ typeset -f foo
foo() {
        OUT=$(( echo foo ; echo $? >&3 | : ) 3>&1 ) && echo "$OUT"
}

… which is a bug in the code that converts $((…)…) from
parsing $((…)) to $(…) and has been fixed in R52. But
mksh R52 has a different bug:

tglase@tglase:~ $ foo() {
> OUT=$( ((echo foo; echo $? 1>&3) | :) 3>&1 ) && echo "$OUT"
> }
tglase@tglase:~ $ typeset -f foo
foo() {
        OUT=$({ ( echo foo ; echo $? >&3 | : ) ; } 3>&1 ) && echo "$OUT"
}

Correct parsing would look like this:

tglase@tglase:~ $ bar() {
> OUT=$( ( (echo foo; echo $? 1>&3) | :) 3>&1 ) && echo "$OUT"
> }
tglase@tglase:~ $ typeset -f bar
bar() {
        OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"
}

Now we have a timing issue though:

tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"
0
tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"

tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"
0
tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"

tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"
0
tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"
0
tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"

tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | : ) 3>&1 ) && echo "$OUT"
0

The problem here is that : returns immediately, so the 3>&1 and
the end of the command substitution may not catch the $? echo’d
any more. The following code is more reliable:

tglase@tglase:~ $ OUT=$(( ( echo foo ; echo $? >&3 ) | sleep 1 ) 3>&1 ) && echo 
"$OUT"
0

>2. In original command large_git produces lots of output to stdout,
>which as described above lands in $OUT both in R51 and R52, but here's
>the awkward difference between the two:
>
>OUT="diff --git"
>test "$OUT" -eq 141 && echo equals || echo not equals

Oh no, you don’t compare strings numerically please.

But this is also a bug that has been fixed in R52.


>Looks like R51 passed git tests only by accident.

Nah, the real cause for the problems here is that the
git tests are broken (replace the “:” with a “sleep 1”
to fix it), plus a parse problem in mksh (which I’ll
fix in R52b now that I know about it).

bye,
//mirabilos
-- 
This space for rent.

Reply via email to