Martijn Dekker
2017-09-26 13:22:42 UTC
I was bitten today by yet another bizarre bug in ksh93.
In the current release version of ksh93 as well as the beta, expansions
like ${var+set} and ${var+:nonempty) do not work correctly when used
within a 'for', 'while' or 'until' loop.
Test script 1:
unset -v var
for i in 1 2 3 4 5; do
case ${var+s} in
( s ) echo set; unset -v var;;
( '' ) echo unset; var=;;
esac
done
Actual output:
unset
unset
unset
unset
unset
Expected output:
unset
set
unset
set
unset
Test script 2:
var=
for i in 1 2 3 4 5; do
case ${var+s} in
( s ) echo set; unset -v var;;
( '' ) echo unset; var=;;
esac
done
Actual output:
set
set
set
set
set
Expected output:
set
unset
set
unset
set
It looks like the expansion remains static within the loop, though it
should change with the variable's set/unset status.
Bizarrely, this bug only applies to ${var+set} and ${var:+nonempty}...
something like ${var-unset} and ${var:-empty} works fine:
unset -v var
for i in 1 2 3 4 5; do
case ${var-u} in
( x ) echo set; unset -v var;;
( u ) echo unset; var=x;;
esac
done
Output (OK):
unset
set
unset
set
unset
Thanks,
- Martijn
In the current release version of ksh93 as well as the beta, expansions
like ${var+set} and ${var+:nonempty) do not work correctly when used
within a 'for', 'while' or 'until' loop.
Test script 1:
unset -v var
for i in 1 2 3 4 5; do
case ${var+s} in
( s ) echo set; unset -v var;;
( '' ) echo unset; var=;;
esac
done
Actual output:
unset
unset
unset
unset
unset
Expected output:
unset
set
unset
set
unset
Test script 2:
var=
for i in 1 2 3 4 5; do
case ${var+s} in
( s ) echo set; unset -v var;;
( '' ) echo unset; var=;;
esac
done
Actual output:
set
set
set
set
set
Expected output:
set
unset
set
unset
set
It looks like the expansion remains static within the loop, though it
should change with the variable's set/unset status.
Bizarrely, this bug only applies to ${var+set} and ${var:+nonempty}...
something like ${var-unset} and ${var:-empty} works fine:
unset -v var
for i in 1 2 3 4 5; do
case ${var-u} in
( x ) echo set; unset -v var;;
( u ) echo unset; var=x;;
esac
done
Output (OK):
unset
set
unset
set
unset
Thanks,
- Martijn