'*' vs. '@' in Korn Shell Array Variables

In order to use the shellcurses functions described at:

Shell Curses function library

I am learning about ksh, which has arrays. My trusty Kochan & Wood book says that for any Korn Shell array AR :

${AR
[*]} expands to all the defined array elements, and

${#AR
[*]} expands to the number of array elements.

But the example programs from the above website use '@' instead of '*' in the two expressions above. Both seem to work. My sample program:

#!/usr/bin/ksh93.att
source /home/lc25487/ksh/shellcurses.ksh
 
MENU[0]="First Menu Line"
MENU[1]="Second Menu Line"
MENU[2]="Third Menu Line"
ITEMCNT=${#MENU[@]}
ITEMCNTSTAR=${#MENU
[*]}
ALLITEMS="${MENU[@]}"
ALLITEMSSTAR="${MENU
[*]}"
echo
echo ITEMCNT = $ITEMCNT
echo ITEMCNTSTAR = $ITEMCNTSTAR
echo ALLITEMS = $ALLITEMS
echo ALLITEMSSTAR = $ALLITEMSSTAR
echo

produces the following output (on AIX 6.1):

==========
lipossrp01ga:/home/lc25487/ksh $ ./t2.ksh

ITEMCNT = 3
ITEMCNTSTAR = 3
ALLITEMS = First Menu Line Second Menu Line Third Menu Line
ALLITEMSSTAR = First Menu Line Second Menu Line Third Menu Line

lipossrp01ga:/home/lc25487/ksh $

What (if anything} is the difference between the usage of @ or * ?

Hi.

The best definition I could find:

1 Like

Thanks Scott, that sounds reasonable, it's kind of like the difference between $* and $@ in the Bourne shell. I'm guessing that there is no difference whatsoever between the two expressions for the number of array elements.

It turns out that the korn shell also has array constructs that supply the indices of an array, from 0 up to the largest defined element, either all-at-once or one-at-a-time in a loop.

For an array AR, ${!AR
[*]} expands to the string "0 1 2 .. N" . So does the construct ${!AR[@]} but this latter povides one subscript at a time in a 'for' loop, while the former consrtruct feeds everything at once. I have expanded my test program:

#!/usr/bin/ksh93.att
 
MENU[0]="First Menu Line"
MENU[1]="Second Menu Line"
MENU[2]="Third Menu Line"
 
ITEMCNT=${#MENU[@]}
ITEMCNTSTAR=${#MENU
[*]}
ALLITEMS="${MENU[@]}"
ALLITEMSSTAR="${MENU
[*]}"
BANGCNT="${!MENU[@]}"
BANGCNTSTAR="${!MENU
[*]}"
 
echo
echo ITEMCNT = $ITEMCNT
echo ITEMCNTSTAR = $ITEMCNTSTAR
echo ALLITEMS = $ALLITEMS
echo ALLITEMSSTAR = $ALLITEMSSTAR
echo BANGCNT = $BANGCNT
echo BANGCNTSTAR = $BANGCNTSTAR
echo
 
echo For Loop for ALLITEMS
echo =================
for STR in "${MENU[@]}"
do
    echo $STR
done
 
echo
echo For Loop for ALLITEMSSTAR
echo =====================
for STR in "${MENU
[*]}"
do
    echo $STR
done
 
echo
echo For Loop for BANGNT
echo ===============
for STR in "${!MENU[@]}"
do
    echo $STR
done
 
echo
echo For Loop for BANGNTSTAR
echo ===================
for STR in "${!MENU
[*]}"
do
    echo $STR
done
echo

When I run it I now get:

 
lipossrp01ga:/home/lc25487/ksh $ ./t2.ksh
 
ITEMCNT = 3
ITEMCNTSTAR = 3
ALLITEMS = First Menu Line Second Menu Line Third Menu Line
ALLITEMSSTAR = First Menu Line Second Menu Line Third Menu Line
BANGCNT = 0 1 2
BANGCNTSTAR = 0 1 2
 
For Loop for ALLITEMS
=================
First Menu Line
Second Menu Line
Third Menu Line
 
For Loop for ALLITEMSSTAR
=====================
First Menu Line Second Menu Line Third Menu Line
 
For Loop for BANGNT
===============
0
1
2
 
For Loop for BANGNTSTAR
===================
0 1 2
 
lipossrp01ga:/home/lc25487/ksh $