Dalam skrip saya memiliki array asosiatif seperti:
declare -A VARS=( ["key1"]="value1" ["key2"]="value" )
Apakah ada satu perintah untuk mengubah itu menjadi daftar parameter dalam formulir
--key1=value1 --key2=value2
tanpa harus menulis ulang secara manual
--key1="${VARS[key1]}" --key2="${VARS[key2]}"
use case yang ada dalam pikiran saya adalah untuk melewatkan array ke skrip sebagai daftar parameter, seperti
my_script.sh $(to_param_list $VARS)
Untuk memperluas komentar yang saya buat di @Kusalananda jawaban, kasus penggunaan tepat saya adalah sebagai berikut: Saya punya skrip yang digunakan untuk membangun installer self-extracting menggunakan makeelf, dan skrip ini menerima beberapa parameter yang harus dipisahkan antara:
- parameter untuk skrip itu sendiri
- parameter untuk installer di dalam installer self-extracting
Script kemudian membangun installer seperti ini:
to_param_list installer_param_list installer_param_array
./makeself ./path/to/sourcedir ./path/to/created/installer "My installer" ./path/to/install/inside/package "${installer_param_list[@]}"
Namun, saya telah menguji parameter yang lewat dengan skrip installer yang sangat sederhana di dalam paket:
while ! -z "$1" ; do
echo "$1"
shift
done
dan melewatkan array seperti:
installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )
hasil dalam output ini:
--upgrade-to=19.3.0
--upgrade-from=19
.2.0
sumber
my_script.sh "$(declare -p thearray)$"
. Dimyscript.sh
Anda membacanya dengansource /dev/stdin <<<"$1"
Lalu Anda milikithearray
di skrip Anda. Anda dapat memiliki argumen lain di samping array. Anda dapat melewati banyak variabel:my_script.sh "$(declare -p var1 var2 ...)"
dalam argumen tunggal ini.Jawaban:
Dengan fungsi pembantu:
Perintah terakhir dalam skrip di atas akan diperluas menjadi setara dengan yang telah ditulis
The
to_param_list
Fungsi mengambil nama dari variabel array dan nama dari variabel array asosiatif dan menggunakan ini untuk membuat dua "referensi nama" variabel dalam fungsi (namerefs diperkenalkan padabash
rilis 4.3). Ini kemudian digunakan untuk mengisi variabel array yang diberikan dengan kunci dan nilai dalam format yang sesuai dari array asosiatif.Pengulangan dalam fungsi berulang
"${!inhash[@]}"
, yang merupakan daftar kunci yang dikutip secara individual dalam array asosiatif Anda.Setelah pemanggilan fungsi kembali, skrip akan menggunakan array untuk memanggil skrip atau perintah Anda yang lain.
Menjalankan di atas dengan
script akan ditampilkan
Ini menunjukkan bahwa opsi dihasilkan tanpa pemisahan kata atau penggumpalan nama file mulai berlaku. Ini juga menunjukkan bahwa urutan kunci tidak dapat dipertahankan karena mengakses kunci dari array asosiatif akan melakukannya dalam urutan yang cukup acak.
Anda tidak dapat benar-benar menggunakan substitusi perintah dengan aman di sini karena itu akan menjadi string tunggal. Jika tidak dikutip, string ini kemudian akan dipisah pada karakter spasi putih (secara default), yang juga akan membagi kunci dan nilai array asosiatif Anda. Shell juga akan melakukan nama file globbing pada kata-kata yang dihasilkan. Mengutip dua kali substitusi perintah tidak akan membantu karena itu akan menghasilkan panggilan Anda
my_script.sh
dengan satu argumen.Mengenai masalah Anda dengan
makeself
:The
makeself
Script melakukan ini dengan argumen untuk installer script Anda:Ini menyimpan argumen sebagai string dalam
$SCRIPTARGS
(disatukan, dipisahkan oleh spasi). Ini kemudian dimasukkan ke dalam arsip self-extracting apa adanya. Agar opsi diuraikan dengan benar ketika mereka dievaluasi kembali (yang mana ketika menjalankan installer), Anda harus memberikan seperangkat tanda kutip tambahan dalam nilai-nilai parameter agar mereka dibatasi secara tepat.Perhatikan bahwa ini bukan bug dalam kode saya. Ini hanya efek samping dari
makeself
pembuatan kode shell berdasarkan nilai yang diberikan pengguna.Idealnya,
makeself
skrip seharusnya menulis masing-masing argumen yang disediakan dengan seperangkat tanda kutip tambahan di sekitar mereka, tetapi tidak, mungkin karena sulit untuk mengetahui efek apa yang mungkin terjadi. Sebagai gantinya, ia menyerahkannya kepada pengguna untuk memberikan penawaran tambahan ini.Menjalankan kembali pengujian saya dari atas, tetapi sekarang dengan
menghasilkan
Anda dapat melihat bahwa string ini , ketika dievaluasi kembali oleh shell, tidak akan terpecah pada spasi.
Jelas, Anda bisa menggunakan array asosiatif awal Anda dan sebagai gantinya menambahkan kutipan dalam
to_param_list
fungsi dengan mengubahke
Salah satu dari perubahan ini pada kode Anda akan menyertakan tanda kutip tunggal dalam nilai-nilai opsi, sehingga evaluasi ulang dari nilai-nilai akan menjadi perlu .
sumber
"--$param=${inhash[$param]}"
atau di dalam"${list[@]}"
, atau skrip yang menerima opsi melakukan kesalahan dalam menguraikannya.