Dengan asumsi Anda ingin membatasi untuk Bourne-seperti kerang (banyak kerang lainnya seperti csh
, tcsh
, rc
, es
atau fish
array dukungan tetapi menulis naskah kompatibel pada saat yang sama untuk Bourne-seperti kerang dan mereka adalah rumit dan umumnya sia-sia karena mereka interpreter untuk benar-benar berbeda dan bahasa yang tidak kompatibel), perhatikan bahwa ada perbedaan signifikan antara implementasi.
Shell Bourne like yang mendukung array adalah:
ksh88
(itulah array implementasi pertama, ksh88 masih ditemukan ksh
pada kebanyakan Unite komersial tradisional yang juga menjadi dasar untuk sh
)
- array adalah satu dimensi
- Array didefinisikan sebagai
set -A array foo bar
atau set -A array -- "$var" ...
jika Anda tidak dapat menjamin bahwa $var
tidak akan mulai dengan -
atau +
.
- Indeks array mulai dari
0
.
- Elemen array individual ditetapkan sebagai
a[1]=value
.
- array jarang. Itu
a[5]=foo
akan bekerja bahkan jika a[0,1,2,3,4]
tidak disetel dan akan membiarkannya tidak disetel.
${a[5]}
untuk mengakses elemen indice 5 (belum tentu elemen ke-6 jika array jarang). The 5
bisa ada ekspresi aritmatika.
- ukuran dan subskrip array terbatas (hingga 4096).
${#a[@]}
adalah jumlah elemen yang ditugaskan dalam array (bukan indice yang ditugaskan terbesar).
- tidak ada cara untuk mengetahui daftar langganan yang ditugaskan (selain menguji 4096 elemen secara individual dengan
[[ -n "${a[i]+set}" ]]
).
$a
sama dengan ${a[0]}
. Itu adalah array yang entah bagaimana memperluas variabel skalar dengan memberi mereka nilai tambahan.
pdksh
dan turunannya (itulah dasar untuk ksh
dan terkadang sh
beberapa BSD dan merupakan satu-satunya implementasi ksh opensource sebelum sumber ksh93 dibebaskan):
Paling suka ksh88
tapi perhatikan:
- Beberapa implementasi lama tidak mendukung
set -A array -- foo bar
, ( --
tidak diperlukan di sana).
${#a[@]}
adalah salah satu plus indice dari indice ditugaskan terbesar. ( a[1000]=1; echo "${#a[@]}"
output 1001 meskipun array hanya memiliki satu elemen.
- dalam versi yang lebih baru, ukuran array tidak lagi terbatas (selain oleh ukuran bilangan bulat).
- versi terbaru dari
mksh
memiliki operator beberapa tambahan terinspirasi dari bash
, ksh93
atau zsh
seperti tugas a la a=(x y)
, a+=(z)
, ${!a[@]}
untuk mendapatkan daftar indeks ditugaskan.
zsh
. zsh
array umumnya dirancang lebih baik dan mengambil yang terbaik dari ksh
dan csh
array. Mereka mirip ksh
tetapi dengan perbedaan signifikan:
- indeks mulai dari 1, bukan 0 (kecuali dalam
ksh
emulasi), itu konsisten dengan array Bourne (parameter posisi $ @, yang zsh
juga mengekspos sebagai array $ argv) dan csh
array.
- mereka adalah tipe yang terpisah dari variabel normal / skalar. Operator berlaku berbeda untuk mereka dan seperti yang biasanya Anda harapkan.
$a
tidak sama dengan ${a[0]}
tetapi memperluas ke elemen array yang tidak kosong ( "${a[@]}"
untuk semua elemen seperti di ksh
).
- mereka adalah array normal, bukan array jarang.
a[5]=1
berfungsi tetapi menetapkan semua elemen dari 1 hingga 4 string kosong jika tidak ditetapkan. Jadi ${#a[@]}
(sama seperti ${#a}
yang di ksh adalah ukuran elemen indice 0) adalah jumlah elemen dalam array dan indice ditugaskan terbesar.
- array asosiatif didukung.
- sejumlah besar operator untuk bekerja dengan array didukung, terlalu besar untuk disebutkan di sini.
- array didefinisikan sebagai
a=(x y)
. set -A a x y
juga berfungsi, tetapi set -A a -- x y
tidak didukung kecuali dalam emulasi ksh ( --
tidak diperlukan dalam emulasi zsh).
ksh93
. (di sini menjelaskan versi terbaru). ksh93
, eksperimental lama dianggap sekarang dapat ditemukan di semakin banyak sistem sekarang yang telah dirilis sebagai FOSS. Sebagai contoh, itu adalah /bin/sh
(di mana ia menggantikan Bourne shell, /usr/xpg4/bin/sh
, POSIX shell masih didasarkan pada ksh88
) dan ksh
dari Solaris 11
. Susunannya memperpanjang dan meningkatkan ksh88.
a=(x y)
dapat digunakan untuk mendefinisikan array, tetapi karena a=(...)
juga digunakan untuk mendefinisikan variabel gabungan ( a=(foo=bar bar=baz)
), a=()
bersifat mendua dan mendeklarasikan variabel gabungan, bukan array.
- array multi-dimensional (
a=((0 1) (0 2))
) dan elemen array juga bisa menjadi variabel majemuk ( a=((a b) (c=d d=f)); echo "${a[1].c}"
).
- Sebuah
a=([2]=foo [5]=bar)
sintaks dapat digunakan untuk mendefinisikan array jarang sekaligus.
- Keterbatasan ukuran diangkat.
- Tidak sampai batas tertentu
zsh
, tetapi sejumlah besar operator didukung juga untuk memanipulasi array.
"${!a[@]}"
untuk mengambil daftar indeks array.
- array asosiatif juga didukung sebagai tipe terpisah.
bash
. bash
adalah shell dari proyek GNU. Ini digunakan seperti sh
pada versi OS / X terbaru dan beberapa distribusi GNU / Linux. bash
array sebagian besar meniru ksh88
yang dengan beberapa fitur ksh93
dan zsh
.
a=(x y)
didukung. set -A a x y
tidak didukung. a=()
membuat array kosong (tidak ada variabel majemuk di bash
).
"${!a[@]}"
untuk daftar indeks.
a=([foo]=bar)
sintaks yang didukung serta beberapa lainnya dari ksh93
dan zsh
.
bash
versi terbaru juga mendukung array asosiatif sebagai tipe terpisah.
yash
. Ini adalah implementasi POSIX sh yang relatif baru, bersih, multi-byte yang disadari. Tidak digunakan secara luas. Arraynya adalah API bersih lain yang mirip denganzsh
- array tidak jarang
- Indeks array mulai dari 1
- didefinisikan (dan dideklarasikan) dengan
a=(var value)
- elemen dimasukkan, dihapus atau dimodifikasi dengan
array
builtin
array -s a 5 value
untuk memodifikasi elemen ke- 5 akan gagal jika elemen itu tidak ditetapkan sebelumnya.
- jumlah elemen dalam array adalah
${a[#]}
, ${#a[@]}
menjadi ukuran elemen sebagai daftar.
- array adalah tipe yang terpisah. Anda perlu
a=("$a")
mendefinisikan ulang variabel skalar sebagai array sebelum Anda dapat menambah atau memodifikasi elemen.
- array tidak didukung ketika dipanggil sebagai
sh
.
Jadi, dari situ Anda dapat melihat bahwa mendeteksi dukungan array, yang dapat Anda lakukan dengan:
if (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'
) > /dev/null 2>&1
then
array_supported=true
else
array_supported=false
fi
tidak cukup untuk dapat menggunakan array itu. Anda perlu mendefinisikan perintah wrapper untuk menetapkan array sebagai elemen keseluruhan dan individual, dan pastikan Anda tidak mencoba membuat array jarang.
Suka
unset a
array_elements() { eval "REPLY=\"\${#$1[@]}\""; }
if (set -A a -- a) 2> /dev/null; then
set -A a -- a b
case ${a[0]}${a[1]} in
--) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=0;;
a) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=1;;
--a) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
ab) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
esac
elif (eval 'a[5]=x') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0
elif (eval 'a=(x) && array -s a 1 y && [ "${a[1]}" = y ]') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() {
eval "
$1=(\${$1+\"\${$1[@]}"'"})
while [ "$(($2))" -ge "${'"$1"'[#]}" ]; do
array -i "$1" "$2" ""
done'
array -s -- "$1" "$((1+$2))" "$3"
}
array_elements() { eval "REPLY=\${$1[#]}"; }
first_indice=1
else
echo >&2 "Array not supported"
fi
Dan kemudian Anda mengakses elemen array dengan "${a[$first_indice+n]}"
, seluruh daftar dengan "${a[@]}"
dan menggunakan fungsi wrapper ( array_elements
, set_array
, set_array_element
) untuk mendapatkan jumlah elemen array (dalam $REPLY
), mengatur array sebagai keseluruhan atau menetapkan unsur-unsur individu.
Mungkin tidak sepadan dengan usaha. Saya akan menggunakan perl
atau batasan untuk Bourne / POSIX shell array yang: "$@"
.
Jika maksudnya untuk memiliki beberapa file yang akan dipasok oleh shell interaktif pengguna untuk mendefinisikan fungsi yang secara internal menggunakan array, berikut adalah beberapa catatan yang mungkin berguna.
Anda dapat mengonfigurasi zsh
array menjadi lebih seperti ksh
array di lingkup lokal (dalam fungsi atau fungsi anonim).
myfunction() {
[ -z "$ZSH_VERSION" ] || setopt localoption ksharrays
# use arrays of indice 0 in this function
}
Anda juga dapat meniru ksh
(meningkatkan kompatibilitas dengan ksh
untuk array dan beberapa area lainnya) dengan:
myfunction() {
[ -z "$ZSH_VERSION" ] || emulate -L ksh
# ksh code more likely to work here
}
Dengan mengingat hal itu dan Anda bersedia melepaskan dukungan untuk yash
dan ksh88
dan versi pdksh
turunan yang lebih lama, dan selama Anda tidak mencoba membuat array jarang, Anda harus dapat menggunakan:
a[0]=foo
a=(foo bar)
(tapi tidak a=()
)
"${a[#]}"
, "${a[@]}"
,"${a[0]}"
dalam fungsi-fungsi yang memiliki emulate -L ksh
, sementara zsh
pengguna masih menggunakan array nya biasanya dengan cara zsh.