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's and ksh&=
#39;s bang (!) expansion flags have different meanings. I don't think t=
his is problematic but other people might disagree and as this difference w=
asn't obvious to me I thought it was worth mentioning here.<div><br></d=
iv><div>In Zsh, the (!) flag means "Don't dereference references&q=
uot;, while in ksh it means "Print the parameter's name instead of=
its value". 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's value with the p=
arameter's name. In ksh, the (!) flag can be used to list the keys of a=
rrays and associative arrays. In that regard, it's closer to Zsh's=
=C2=A0(k) flag than Zsh'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 "str =C2=A0 :${(k)str}"</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 "str[1]:${(k)str[1]}"</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 "str[*]:${(k)str[*]}"</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 "arr =C2=A0 :${(k)arr}"</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 "arr[1]:${(k)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:tra=
nsparent;font-variant:normal;vertical-align:baseline;white-space:pre-wrap">=
echo "arr[*]:${(k)arr[*]}"</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 =
"ass =C2=A0 :${(k)ass}"</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]}"</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 "as=
s[*]:${(k)ass[*]}"</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 "str =C2=A0 :${!str}"</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 "str[1]:${!str[1]}"</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[*]}"</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 "arr =
=C2=A0 :${!arr}"</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 "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:transparent;font-variant:norma=
l;vertical-align:baseline;white-space:pre-wrap">echo "arr[*]:${!arr[*]=
}"</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 "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 "ass[Y]:${!ass[Y]}"</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 "ass[*]:${!ass[*]}"</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 "str =C2=A0 :${!str}"</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 "str[1]:${!str[1]}"</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[*]}"</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 "arr =
=C2=A0 :${!arr}"</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 "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:transparent;font-variant:norma=
l;vertical-align:baseline;white-space:pre-wrap">echo "arr[*]:${!arr[*]=
}"</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 "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 "ass[Y]:${!ass[Y]}"</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 "ass[*]:${!ass[*]}"</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 "${(k)ass[Y]}" returns just "Y", while in ksh &qu=
ot;${!ass[Y]}" returns "ass[Y]". To me, the former looks mor=
e consistent with the behavior for "ass[*]".</div></div><div><br>=
</div><div>Another difference is that in Zsh the (k) flag doesn't work =
for array ranges ("${(k)arr[*]}" returns "aa bb cc"), w=
hile in ksh it does ("${!arr[*]}" returns "0 1 2"). 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--