Zsh's and ksh's bang (!) expansion flags have different meanings

Philippe Altherr <[email protected]> Sun, 19 Jul 2026 17:50:39 +0200
Newsgroups gmane.comp.shells.zsh.devel
Message-ID <CAGdYchvRE_B4b0yuk9drdR3dKb-2ci5r9PC5mUsVQ=x8tm2-1g@mail.gmail.com>
--000000000000013a590656f8c1da
Content-Type: text/plain; charset="UTF-8"

In some recent work I noticed that Zsh's and ksh's bang (!) expansion flags
have different meanings. I don't think this is problematic but other people
might disagree and as this difference wasn't obvious to me I thought it was
worth mentioning here.

In Zsh, the (!) flag means "Don't dereference references", while in ksh it
means "Print the parameter's name instead of its value". The difference is
the most striking on chains of references:

Zsh

Zsh in ksh emulation

ksh

typeset var0=foo

typeset -n ref1=var0 ref2=ref1 ref3=ref2

echo var0:${(!)var0}

echo ref1:${(!)ref1}

echo ref2:${(!)ref2}

echo ref3:${(!)ref3}

emulate ksh

typeset var0=foo

typeset -n ref1=var0 ref2=ref1 ref3=ref2

echo var0:${!var0}

echo ref1:${!ref1}

echo ref2:${!ref2}

echo ref3:${!ref3}

typeset var0=foo

typeset -n ref1=var0 ref2=ref1 ref3=ref2

echo var0:${!var0}

echo ref1:${!ref1}

echo ref2:${!ref2}

echo ref3:${!ref3}

var0:foo

ref1:var0

ref2:ref1

ref3:ref2

var0:foo

ref1:var0

ref2:ref1

ref3:ref2

var0:var0

ref1:var0

ref2:var0

ref3:var0

In Zsh, the (!) flag only makes a difference when the parameter is a
reference, while in ksh it always makes a difference; it always replaces
the parameter's value with the parameter's name. In ksh, the (!) flag can
be used to list the keys of arrays and associative arrays. In that regard,
it's closer to Zsh's (k) flag than Zsh's (!) flag:

Zsh

Zsh in ksh emulation

ksh

typeset str=abc

typeset -a arr=(aa bb cc)

typeset -A ass=(X xx Y yy Z zz)

echo "str   :${(k)str}"

echo "str[1]:${(k)str[1]}"

echo "str[*]:${(k)str[*]}"

echo "arr   :${(k)arr}"

echo "arr[1]:${(k)arr[1]}"

echo "arr[*]:${(k)arr[*]}"

echo "ass   :${(k)ass}"

echo "ass[Y]:${(k)ass[Y]}"

echo "ass[*]:${(k)ass[*]}"

emulate ksh

typeset str=abc

typeset -a arr=(aa bb cc)

typeset -A ass=([X]=xx [Y]=yy [Z]=zz)

echo "str   :${!str}"

echo "str[1]:${!str[1]}"

echo "str[*]:${!str[*]}"

echo "arr   :${!arr}"

echo "arr[1]:${!arr[1]}"

echo "arr[*]:${!arr[*]}"

echo "ass   :${!ass}"

echo "ass[Y]:${!ass[Y]}"

echo "ass[*]:${!ass[*]}"

typeset str=abc

typeset -a arr=(aa bb cc)

typeset -A ass=([X]=xx [Y]=yy [Z]=zz)

echo "str   :${!str}"

echo "str[1]:${!str[1]}"

echo "str[*]:${!str[*]}"

echo "arr   :${!arr}"

echo "arr[1]:${!arr[1]}"

echo "arr[*]:${!arr[*]}"

echo "ass   :${!ass}"

echo "ass[Y]:${!ass[Y]}"

echo "ass[*]:${!ass[*]}"

str   :abc

str[1]:a

str[*]:abc

arr   :aa bb cc

arr[1]:1

arr[*]:aa bb cc

ass   :X Y Z

ass[Y]:Y

ass[*]:X Y Z

str   :abc

str[1]:b

str[*]:abc

arr   :aa

arr[1]:1

arr[*]:aa bb cc

ass   :

ass[Y]:Y

ass[*]:X Y Z

str   :str

str[1]:str[1]

str[*]:0

arr   :arr

arr[1]:arr[1]

arr[*]:0 1 2

ass   :ass

ass[Y]:ass[Y]

ass[*]:X Y Z

One difference is that in Zsh "${(k)ass[Y]}" returns just "Y", while in ksh
"${!ass[Y]}" returns "ass[Y]". To me, the former looks more consistent with
the behavior for "ass[*]".

Another difference is that in Zsh the (k) flag doesn't work for array
ranges ("${(k)arr[*]}" returns "aa bb cc"), while in ksh it does
("${!arr[*]}" returns "0 1 2"). To me, this looks like something that ought
to be changed in Zsh. In conjunction with the (v) flag, it could be used to
list array values interleaved with their indexes.

Philippe

--000000000000013a590656f8c1da
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">In some recent work I noticed that=C2=A0Zsh&#39;s and ksh&=
#39;s bang (!) expansion flags have different meanings. I don&#39;t think t=
his is problematic but other people might disagree and as this difference w=
asn&#39;t obvious to me I thought it was worth mentioning here.<div><br></d=
iv><div>In Zsh, the (!) flag means &quot;Don&#39;t dereference references&q=
uot;, while in ksh it means &quot;Print the parameter&#39;s name instead of=
 its value&quot;. The difference is the most striking=C2=A0on chains of ref=
erences:</div><div><br></div><div><div><span id=3D"gmail-docs-internal-guid=
-3ca1de4f-7fff-eae0-0dfb-89bf0e064adf"><div dir=3D"ltr" style=3D"margin-lef=
t:0pt" align=3D"left"><table style=3D"border-width:medium;border-style:none=
;border-color:currentcolor;border-collapse:collapse"><colgroup><col width=
=3D"310"><col width=3D"310"><col width=3D"310"></colgroup><tbody><tr style=
=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;border-col=
or:rgb(0,0,0);vertical-align:top;background-color:rgb(204,204,204);padding:=
5pt;overflow:hidden"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt=
;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Arial,sans-se=
rif;color:rgb(0,0,0);background-color:transparent;font-variant:normal;verti=
cal-align:baseline;white-space:pre-wrap">Zsh</span></p></td><td style=3D"bo=
rder-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:to=
p;background-color:rgb(204,204,204);padding:5pt;overflow:hidden"><p dir=3D"=
ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:10pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background=
-color:transparent;font-variant:normal;vertical-align:baseline;white-space:=
pre-wrap">Zsh in ksh emulation</span></p></td><td style=3D"border-width:1pt=
;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;background-c=
olor:rgb(204,204,204);padding:5pt;overflow:hidden"><p dir=3D"ltr" style=3D"=
line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
10pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transpa=
rent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">ksh<=
/span></p></td></tr><tr style=3D"height:0pt"><td style=3D"border-width:1pt;=
border-style:solid;border-color:rgb(0,0,0);vertical-align:top;background-co=
lor:rgb(239,239,239);padding:5pt;overflow:hidden"><font face=3D"monospace">=
<br></font><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"color:rgb(0,0,0);background-color:transparent;font=
-variant:normal;vertical-align:baseline;white-space:pre-wrap"><font face=3D=
"monospace">typeset var0=3Dfoo</font></span></p><p dir=3D"ltr" style=3D"lin=
e-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0=
,0);background-color:transparent;font-variant:normal;vertical-align:baselin=
e;white-space:pre-wrap"><font face=3D"monospace">typeset -n ref1=3Dvar0 ref=
2=3Dref1 ref3=3Dref2</font></span></p><p dir=3D"ltr" style=3D"line-height:1=
.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant:normal;vertical-align:baseline;white-sp=
ace:pre-wrap"><font face=3D"monospace">echo var0:${(!)var0}</font></span></=
p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"color:rgb(0,0,0);background-color:transparent;font-variant:=
normal;vertical-align:baseline;white-space:pre-wrap"><font face=3D"monospac=
e">echo ref1:${(!)ref1}</font></span></p><p dir=3D"ltr" style=3D"line-heigh=
t:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);bac=
kground-color:transparent;font-variant:normal;vertical-align:baseline;white=
-space:pre-wrap"><font face=3D"monospace">echo ref2:${(!)ref2}</font></span=
></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"color:rgb(0,0,0);background-color:transparent;font-varia=
nt:normal;vertical-align:baseline;white-space:pre-wrap"><font face=3D"monos=
pace">echo ref3:${(!)ref3}</font></span></p></td><td style=3D"border-width:=
1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;backgroun=
d-color:rgb(239,239,239);padding:5pt;overflow:hidden"><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:=
rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-align:=
baseline;white-space:pre-wrap"><font face=3D"monospace">emulate ksh</font><=
/span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bot=
tom:0pt"><span style=3D"color:rgb(0,0,0);background-color:transparent;font-=
variant:normal;vertical-align:baseline;white-space:pre-wrap"><font face=3D"=
monospace">typeset var0=3Dfoo</font></span></p><p dir=3D"ltr" style=3D"line=
-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,=
0);background-color:transparent;font-variant:normal;vertical-align:baseline=
;white-space:pre-wrap"><font face=3D"monospace">typeset -n ref1=3Dvar0 ref2=
=3Dref1 ref3=3Dref2</font></span></p><p dir=3D"ltr" style=3D"line-height:1.=
2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);backgro=
und-color:transparent;font-variant:normal;vertical-align:baseline;white-spa=
ce:pre-wrap"><font face=3D"monospace">echo var0:${!var0}</font></span></p><=
p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"color:rgb(0,0,0);background-color:transparent;font-variant:nor=
mal;vertical-align:baseline;white-space:pre-wrap"><font face=3D"monospace">=
echo ref1:${!ref1}</font></span></p><p dir=3D"ltr" style=3D"line-height:1.2=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant:normal;vertical-align:baseline;white-spac=
e:pre-wrap"><font face=3D"monospace">echo ref2:${!ref2}</font></span></p><p=
 dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"color:rgb(0,0,0);background-color:transparent;font-variant:norm=
al;vertical-align:baseline;white-space:pre-wrap"><font face=3D"monospace">e=
cho ref3:${!ref3}</font></span></p></td><td style=3D"border-width:1pt;borde=
r-style:solid;border-color:rgb(0,0,0);vertical-align:top;background-color:r=
gb(239,239,239);padding:5pt;overflow:hidden"><font face=3D"monospace"><br><=
/font><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"color:rgb(0,0,0);background-color:transparent;font-vari=
ant:normal;vertical-align:baseline;white-space:pre-wrap"><font face=3D"mono=
space">typeset var0=3Dfoo</font></span></p><p dir=3D"ltr" style=3D"line-hei=
ght:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);b=
ackground-color:transparent;font-variant:normal;vertical-align:baseline;whi=
te-space:pre-wrap"><font face=3D"monospace">typeset -n ref1=3Dvar0 ref2=3Dr=
ef1 ref3=3Dref2</font></span></p><p dir=3D"ltr" style=3D"line-height:1.2;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);background-=
color:transparent;font-variant:normal;vertical-align:baseline;white-space:p=
re-wrap"><font face=3D"monospace">echo var0:${!var0}</font></span></p><p di=
r=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"color:rgb(0,0,0);background-color:transparent;font-variant:normal;=
vertical-align:baseline;white-space:pre-wrap"><font face=3D"monospace">echo=
 ref1:${!ref1}</font></span></p><p dir=3D"ltr" style=3D"line-height:1.2;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);background-c=
olor:transparent;font-variant:normal;vertical-align:baseline;white-space:pr=
e-wrap"><font face=3D"monospace">echo ref2:${!ref2}</font></span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"color:rgb(0,0,0);background-color:transparent;font-variant:normal;v=
ertical-align:baseline;white-space:pre-wrap"><font face=3D"monospace">echo =
ref3:${!ref3}</font></span></p></td></tr><tr style=3D"height:0pt"><td style=
=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-al=
ign:top;padding:5pt;overflow:hidden"><p dir=3D"ltr" style=3D"line-height:1.=
2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);backgro=
und-color:transparent;font-variant:normal;vertical-align:baseline;white-spa=
ce:pre-wrap"><font face=3D"monospace">var0:foo</font></span></p><p dir=3D"l=
tr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"color:rgb(0,0,0);background-color:transparent;font-variant:normal;verti=
cal-align:baseline;white-space:pre-wrap"><font face=3D"monospace">ref1:var0=
</font></span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"color:rgb(0,0,0);background-color:transpare=
nt;font-variant:normal;vertical-align:baseline;white-space:pre-wrap"><font =
face=3D"monospace">ref2:ref1</font></span></p><p dir=3D"ltr" style=3D"line-=
height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0=
);background-color:transparent;font-variant:normal;vertical-align:baseline;=
white-space:pre-wrap"><font face=3D"monospace">ref3:ref2</font></span></p><=
/td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0=
);vertical-align:top;padding:5pt;overflow:hidden"><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0=
,0,0);background-color:transparent;font-variant:normal;vertical-align:basel=
ine;white-space:pre-wrap"><font face=3D"monospace">var0:foo</font></span></=
p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"color:rgb(0,0,0);background-color:transparent;font-variant:=
normal;vertical-align:baseline;white-space:pre-wrap"><font face=3D"monospac=
e">ref1:var0</font></span></p><p dir=3D"ltr" style=3D"line-height:1.2;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);background-col=
or:transparent;font-variant:normal;vertical-align:baseline;white-space:pre-=
wrap"><font face=3D"monospace">ref2:ref1</font></span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"col=
or:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-ali=
gn:baseline;white-space:pre-wrap"><font face=3D"monospace">ref3:ref2</font>=
</span></p></td><td style=3D"border-width:1pt;border-style:solid;border-col=
or:rgb(0,0,0);vertical-align:top;padding:5pt;overflow:hidden"><p dir=3D"ltr=
" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D=
"color:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical=
-align:baseline;white-space:pre-wrap"><font face=3D"monospace">var0:var0</f=
ont></span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margi=
n-bottom:0pt"><span style=3D"color:rgb(0,0,0);background-color:transparent;=
font-variant:normal;vertical-align:baseline;white-space:pre-wrap"><font fac=
e=3D"monospace">ref1:var0</font></span></p><p dir=3D"ltr" style=3D"line-hei=
ght:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"color:rgb(0,0,0);b=
ackground-color:transparent;font-variant:normal;vertical-align:baseline;whi=
te-space:pre-wrap"><font face=3D"monospace">ref2:var0</font></span></p><p d=
ir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span=
 style=3D"color:rgb(0,0,0);background-color:transparent;font-variant:normal=
;vertical-align:baseline;white-space:pre-wrap"><font face=3D"monospace" sty=
le=3D"">ref3:var0</font></span></p></td></tr></tbody></table></div></span><=
/div><div><span style=3D"background-color:transparent"><br></span></div><di=
v><span style=3D"background-color:transparent">In Zsh, the (!) flag only ma=
kes a difference when the parameter is a reference, while in ksh it always =
makes a difference; it always replaces the parameter&#39;s value with the p=
arameter&#39;s name. In ksh, the (!) flag can be used to list the keys of a=
rrays and associative arrays. In that regard, it&#39;s closer to Zsh&#39;s=
=C2=A0(k) flag than Zsh&#39;s (!) flag</span><span style=3D"background-colo=
r:transparent">:</span></div><div><span style=3D"background-color:transpare=
nt"><br></span></div><div><span id=3D"gmail-docs-internal-guid-8ef0c368-7ff=
f-206e-ca62-aeb4caaeafcc"><div dir=3D"ltr" style=3D"margin-left:0pt" align=
=3D"left"><table style=3D"border-width:medium;border-style:none;border-colo=
r:currentcolor;border-collapse:collapse"><colgroup><col width=3D"310"><col =
width=3D"310"><col width=3D"310"></colgroup><tbody><tr style=3D"height:0pt"=
><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);v=
ertical-align:top;background-color:rgb(204,204,204);padding:5pt;overflow:hi=
dden"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:10pt;font-family:Arial,sans-serif;color:rgb(0=
,0,0);background-color:transparent;font-variant:normal;vertical-align:basel=
ine;white-space:pre-wrap">Zsh</span></p></td><td style=3D"border-width:1pt;=
border-style:solid;border-color:rgb(0,0,0);vertical-align:top;background-co=
lor:rgb(204,204,204);padding:5pt;overflow:hidden"><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transpar=
ent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">Zsh i=
n ksh emulation</span></p></td><td style=3D"border-width:1pt;border-style:s=
olid;border-color:rgb(0,0,0);vertical-align:top;background-color:rgb(204,20=
4,204);padding:5pt;overflow:hidden"><p dir=3D"ltr" style=3D"line-height:1.2=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-famil=
y:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-varia=
nt:normal;vertical-align:baseline;white-space:pre-wrap">ksh</span></p></td>=
</tr><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:so=
lid;border-color:rgb(0,0,0);vertical-align:top;background-color:rgb(239,239=
,239);padding:5pt;overflow:hidden"><br><p dir=3D"ltr" style=3D"line-height:=
1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fa=
mily:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font=
-variant:normal;vertical-align:baseline;white-space:pre-wrap">typeset str=
=3Dabc</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-ser=
if;color:rgb(0,0,0);background-color:transparent;font-variant:normal;vertic=
al-align:baseline;white-space:pre-wrap">typeset -a arr=3D(aa bb cc)</span><=
/p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0=
,0,0);background-color:transparent;font-variant:normal;vertical-align:basel=
ine;white-space:pre-wrap">typeset -A ass=3D(X xx Y yy Z zz)</span></p><p di=
r=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant:normal;vertical-align:baseline;whit=
e-space:pre-wrap">echo &quot;str =C2=A0 :${(k)str}&quot;</span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);bac=
kground-color:transparent;font-variant:normal;vertical-align:baseline;white=
-space:pre-wrap">echo &quot;str[1]:${(k)str[1]}&quot;</span></p><p dir=3D"l=
tr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);backgro=
und-color:transparent;font-variant:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">echo &quot;str[*]:${(k)str[*]}&quot;</span></p><p dir=3D"ltr" =
style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-c=
olor:transparent;font-variant:normal;vertical-align:baseline;white-space:pr=
e-wrap">echo &quot;arr =C2=A0 :${(k)arr}&quot;</span></p><p dir=3D"ltr" sty=
le=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font=
-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-colo=
r:transparent;font-variant:normal;vertical-align:baseline;white-space:pre-w=
rap">echo &quot;arr[1]:${(k)arr[1]}&quot;</span></p><p dir=3D"ltr" style=3D=
"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size=
:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:tra=
nsparent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">=
echo &quot;arr[*]:${(k)arr[*]}&quot;</span></p><p dir=3D"ltr" style=3D"line=
-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt=
;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transpar=
ent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">echo =
&quot;ass =C2=A0 :${(k)ass}&quot;</span></p><p dir=3D"ltr" style=3D"line-he=
ight:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;fo=
nt-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent=
;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">echo &qu=
ot;ass[Y]:${(k)ass[Y]}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:=
1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fa=
mily:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font=
-variant:normal;vertical-align:baseline;white-space:pre-wrap">echo &quot;as=
s[*]:${(k)ass[*]}&quot;</span></p></td><td style=3D"border-width:1pt;border=
-style:solid;border-color:rgb(0,0,0);vertical-align:top;background-color:rg=
b(239,239,239);padding:5pt;overflow:hidden"><p dir=3D"ltr" style=3D"line-he=
ight:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;fo=
nt-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent=
;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">emulate =
ksh</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;=
color:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-=
align:baseline;white-space:pre-wrap">typeset str=3Dabc</span></p><p dir=3D"=
ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);backgro=
und-color:transparent;font-variant:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">typeset -a arr=3D(aa bb cc)</span></p><p dir=3D"ltr" style=3D"=
line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:tran=
sparent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">t=
ypeset -A ass=3D([X]=3Dxx [Y]=3Dyy [Z]=3Dzz)</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:=
transparent;font-variant:normal;vertical-align:baseline;white-space:pre-wra=
p">echo &quot;str =C2=A0 :${!str}&quot;</span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:trans=
parent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">ec=
ho &quot;str[1]:${!str[1]}&quot;</span></p><p dir=3D"ltr" style=3D"line-hei=
ght:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;fon=
t-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;=
font-variant:normal;vertical-align:baseline;white-space:pre-wrap">echo &quo=
t;str[*]:${!str[*]}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:1.2=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-famil=
y:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font-va=
riant:normal;vertical-align:baseline;white-space:pre-wrap">echo &quot;arr =
=C2=A0 :${!arr}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Co=
nsolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font-varian=
t:normal;vertical-align:baseline;white-space:pre-wrap">echo &quot;arr[1]:${=
!arr[1]}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top=
:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,=
sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant:norma=
l;vertical-align:baseline;white-space:pre-wrap">echo &quot;arr[*]:${!arr[*]=
}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-se=
rif;color:rgb(0,0,0);background-color:transparent;font-variant:normal;verti=
cal-align:baseline;white-space:pre-wrap">echo &quot;ass =C2=A0 :${!ass}&quo=
t;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;c=
olor:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-a=
lign:baseline;white-space:pre-wrap">echo &quot;ass[Y]:${!ass[Y]}&quot;</spa=
n></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rg=
b(0,0,0);background-color:transparent;font-variant:normal;vertical-align:ba=
seline;white-space:pre-wrap">echo &quot;ass[*]:${!ass[*]}&quot;</span></p><=
/td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0=
);vertical-align:top;background-color:rgb(239,239,239);padding:5pt;overflow=
:hidden"><br><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;c=
olor:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-a=
lign:baseline;white-space:pre-wrap">typeset str=3Dabc</span></p><p dir=3D"l=
tr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);backgro=
und-color:transparent;font-variant:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">typeset -a arr=3D(aa bb cc)</span></p><p dir=3D"ltr" style=3D"=
line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:tran=
sparent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">t=
ypeset -A ass=3D([X]=3Dxx [Y]=3Dyy [Z]=3Dzz)</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:=
transparent;font-variant:normal;vertical-align:baseline;white-space:pre-wra=
p">echo &quot;str =C2=A0 :${!str}&quot;</span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:trans=
parent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">ec=
ho &quot;str[1]:${!str[1]}&quot;</span></p><p dir=3D"ltr" style=3D"line-hei=
ght:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;fon=
t-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;=
font-variant:normal;vertical-align:baseline;white-space:pre-wrap">echo &quo=
t;str[*]:${!str[*]}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:1.2=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-famil=
y:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font-va=
riant:normal;vertical-align:baseline;white-space:pre-wrap">echo &quot;arr =
=C2=A0 :${!arr}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Co=
nsolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font-varian=
t:normal;vertical-align:baseline;white-space:pre-wrap">echo &quot;arr[1]:${=
!arr[1]}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top=
:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,=
sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant:norma=
l;vertical-align:baseline;white-space:pre-wrap">echo &quot;arr[*]:${!arr[*]=
}&quot;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-se=
rif;color:rgb(0,0,0);background-color:transparent;font-variant:normal;verti=
cal-align:baseline;white-space:pre-wrap">echo &quot;ass =C2=A0 :${!ass}&quo=
t;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;c=
olor:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-a=
lign:baseline;white-space:pre-wrap">echo &quot;ass[Y]:${!ass[Y]}&quot;</spa=
n></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rg=
b(0,0,0);background-color:transparent;font-variant:normal;vertical-align:ba=
seline;white-space:pre-wrap">echo &quot;ass[*]:${!ass[*]}&quot;</span></p><=
/td></tr><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-styl=
e:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt;overflow:hid=
den"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb=
(0,0,0);background-color:transparent;font-variant:normal;vertical-align:bas=
eline;white-space:pre-wrap">str =C2=A0 :abc</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:=
transparent;font-variant:normal;vertical-align:baseline;white-space:pre-wra=
p">str[1]:a</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,san=
s-serif;color:rgb(0,0,0);background-color:transparent;font-variant:normal;v=
ertical-align:baseline;white-space:pre-wrap">str[*]:abc</span></p><p dir=3D=
"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span styl=
e=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">arr =C2=A0 :aa bb cc</span></p><p dir=3D"ltr" style=3D"line-h=
eight:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;f=
ont-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparen=
t;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">arr[1]:=
1</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;co=
lor:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-al=
ign:baseline;white-space:pre-wrap">arr[*]:aa bb cc</span></p><p dir=3D"ltr"=
 style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-=
color:transparent;font-variant:normal;vertical-align:baseline;white-space:p=
re-wrap">ass =C2=A0 :X Y Z</span></p><p dir=3D"ltr" style=3D"line-height:1.=
2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fami=
ly:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font-v=
ariant:normal;vertical-align:baseline;white-space:pre-wrap">ass[Y]:Y</span>=
</p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(=
0,0,0);background-color:transparent;font-variant:normal;vertical-align:base=
line;white-space:pre-wrap">ass[*]:X Y Z</span></p></td><td style=3D"border-=
width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pad=
ding:5pt;overflow:hidden"><p dir=3D"ltr" style=3D"line-height:1.2;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas=
,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant:norm=
al;vertical-align:baseline;white-space:pre-wrap">str =C2=A0 :abc</span></p>=
<p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><=
span style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,=
0);background-color:transparent;font-variant:normal;vertical-align:baseline=
;white-space:pre-wrap">str[1]:b</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font=
-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;f=
ont-variant:normal;vertical-align:baseline;white-space:pre-wrap">str[*]:abc=
</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;col=
or:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">arr =C2=A0 :aa</span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-co=
lor:transparent;font-variant:normal;vertical-align:baseline;white-space:pre=
-wrap">arr[1]:1</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas=
,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant:norm=
al;vertical-align:baseline;white-space:pre-wrap">arr[*]:aa bb cc</span></p>=
<p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><=
span style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,=
0);background-color:transparent;font-variant:normal;vertical-align:baseline=
;white-space:pre-wrap">ass =C2=A0 :</span></p><p dir=3D"ltr" style=3D"line-=
height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;=
font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transpare=
nt;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">ass[Y]=
:Y</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;c=
olor:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-a=
lign:baseline;white-space:pre-wrap">ass[*]:X Y Z</span></p></td><td style=
=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-al=
ign:top;padding:5pt;overflow:hidden"><p dir=3D"ltr" style=3D"line-height:1.=
2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fami=
ly:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font-v=
ariant:normal;vertical-align:baseline;white-space:pre-wrap">str =C2=A0 :str=
</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-serif;col=
or:rgb(0,0,0);background-color:transparent;font-variant:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">str[1]:str[1]</span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);background-col=
or:transparent;font-variant:normal;vertical-align:baseline;white-space:pre-=
wrap">str[*]:0</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top=
:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,=
sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant:norma=
l;vertical-align:baseline;white-space:pre-wrap">arr =C2=A0 :arr</span></p><=
p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0=
);background-color:transparent;font-variant:normal;vertical-align:baseline;=
white-space:pre-wrap">arr[1]:arr[1]</span></p><p dir=3D"ltr" style=3D"line-=
height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;=
font-family:Consolas,sans-serif;color:rgb(0,0,0);background-color:transpare=
nt;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">arr[*]=
:0 1 2</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Consolas,sans-ser=
if;color:rgb(0,0,0);background-color:transparent;font-variant:normal;vertic=
al-align:baseline;white-space:pre-wrap">ass =C2=A0 :ass</span></p><p dir=3D=
"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span styl=
e=3D"font-size:10pt;font-family:Consolas,sans-serif;color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">ass[Y]:ass[Y]</span></p><p dir=3D"ltr" style=3D"line-height:1=
.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fam=
ily:Consolas,sans-serif;color:rgb(0,0,0);background-color:transparent;font-=
variant:normal;vertical-align:baseline;white-space:pre-wrap">ass[*]:X Y Z</=
span></p></td></tr></tbody></table></div></span></div><div><span style=3D"b=
ackground-color:transparent"><br></span></div><div>One difference is that i=
n Zsh &quot;${(k)ass[Y]}&quot; returns just &quot;Y&quot;, while in ksh &qu=
ot;${!ass[Y]}&quot; returns &quot;ass[Y]&quot;. To me, the former looks mor=
e consistent with the behavior for &quot;ass[*]&quot;.</div></div><div><br>=
</div><div>Another difference is that in Zsh the (k) flag doesn&#39;t work =
for array ranges (&quot;${(k)arr[*]}&quot; returns &quot;aa bb cc&quot;), w=
hile in ksh it does (&quot;${!arr[*]}&quot; returns &quot;0 1 2&quot;). To =
me, this looks like something that ought to be changed in Zsh. In conjuncti=
on with the (v) flag, it could be used to list array values interleaved wit=
h their indexes.</div><div><br></div><div>Philippe</div><div><br></div></di=
v>

--000000000000013a590656f8c1da--