Bash, sejak versi 4.3, Februari 2014 (?), Memiliki dukungan eksplisit untuk variabel referensi atau referensi nama (namerefs), di luar "eval", dengan kinerja manfaat dan efek tipuan yang sama, dan yang mungkin lebih jelas dalam skrip Anda dan juga lebih sulit untuk "lupa untuk 'eval' dan harus memperbaiki kesalahan ini":
declare [-aAfFgilnrtux] [-p] [name[=value] ...]
typeset [-aAfFgilnrtux] [-p] [name[=value] ...]
Declare variables and/or give them attributes
...
-n Give each name the nameref attribute, making it a name reference
to another variable. That other variable is defined by the value
of name. All references and assignments to name, except for⋅
changing the -n attribute itself, are performed on the variable
referenced by name's value. The -n attribute cannot be applied to
array variables.
...
When used in a function, declare and typeset make each name local,
as with the local command, unless the -g option is supplied...
dan juga:
PARAMETER
Sebuah variabel dapat diberi atribut nameref menggunakan opsi -n ke perintah mendeklarasikan atau perintah builtin lokal (lihat deskripsi mendeklarasikan dan lokal di bawah) untuk membuat nameref, atau referensi ke variabel lain. Ini memungkinkan variabel untuk dimanipulasi secara tidak langsung. Setiap kali variabel nameref direferensikan atau ditugaskan, operasi sebenarnya dilakukan pada variabel yang ditentukan oleh nilai variabel nameref. Nameref biasanya digunakan dalam fungsi shell untuk merujuk ke variabel yang namanya dilewatkan sebagai argumen ke⋅ fungsi. Misalnya, jika nama variabel dilewatkan ke fungsi shell sebagai argumen pertamanya, jalankan
declare -n ref=$1
di dalam fungsi menciptakan ref variabel nameref yang nilainya adalah nama variabel yang diteruskan sebagai argumen pertama. Referensi dan penugasan ke ref diperlakukan sebagai referensi dan penugasan ke variabel yang namanya disahkan sebagai $ 1. Jika variabel kontrol dalam for for memiliki atribut nameref, daftar kata-kata bisa menjadi daftar variabel shell, dan referensi nama akan⋅dibuat untuk setiap kata dalam daftar, pada gilirannya, ketika loop dijalankan. Variabel array tidak dapat diberi atribut -n. Namun, variabel nameref dapat merujuk variabel array dan variabel array yang disubkripsikan. Namerefs dapat⋅ tidak disetel menggunakan opsi -n ke unset builtin. Jika tidak, jika tidak disetel dijalankan dengan nama variabel nameref sebagai argumen,
Misalnya ( EDIT 2 : (terima kasih Ron) namespaced (diawali) nama variabel fungsi-internal, untuk meminimalkan benturan variabel eksternal, yang akhirnya harus menjawab dengan benar, masalah yang diangkat dalam komentar oleh Karsten):
# $1 : string; your variable to contain the return value
function return_a_string () {
declare -n ret=$1
local MYLIB_return_a_string_message="The date is "
MYLIB_return_a_string_message+=$(date)
ret=$MYLIB_return_a_string_message
}
dan menguji contoh ini:
$ return_a_string result; echo $result
The date is 20160817
Perhatikan bahwa bash "menyatakan" builtin, ketika digunakan dalam suatu fungsi, menjadikan variabel yang dideklarasikan "lokal" secara default, dan "-n" juga dapat digunakan dengan "lokal".
Saya lebih suka membedakan variabel "mendeklarasikan penting" dari variabel "membosankan lokal", jadi menggunakan "menyatakan" dan "lokal" dengan cara ini bertindak sebagai dokumentasi.
EDIT 1 - (Tanggapan terhadap komentar di bawah oleh Karsten) - Saya tidak dapat menambahkan komentar di bawah ini lagi, tetapi komentar Karsten membuat saya berpikir, jadi saya melakukan tes berikut yang BEKERJA HALUS, AFAICT - Karsten jika Anda membaca ini, berikan set yang tepat langkah uji dari baris perintah, menunjukkan masalah yang Anda asumsikan ada, karena langkah-langkah berikut ini berfungsi dengan baik:
$ return_a_string ret; echo $ret
The date is 20170104
(Saya menjalankan ini sekarang, setelah menempelkan fungsi di atas ke dalam istilah bash - seperti yang Anda lihat, hasilnya bekerja dengan baik.)
function funcName {
sintaksis pra-POSIX warisan diwarisi dari ksh awal (di mana ada perbedaan semantik yang bash tidak menghormati).funcName() {
, tanpafunction
, harus digunakan sebagai gantinya; lihat wiki.bash-hackers.org/scripting/obsolete