Ketika saya mengerti maksud Anda, saya tidak percaya bahwa salah satu dari jawaban ini benar. eval
tidak perlu dengan cara apa pun, Anda juga tidak perlu bahkan dua kali mengevaluasi variabel Anda.
Memang benar, @Gilles sangat dekat, tetapi dia tidak membahas masalah kemungkinan nilai-nilai utama dan bagaimana mereka harus digunakan jika Anda membutuhkannya lebih dari sekali. Lagi pula, templat harus digunakan lebih dari sekali, bukan?
Saya pikir ini lebih merupakan urutan di mana Anda mengevaluasi mereka yang penting. Pertimbangkan yang berikut ini:
TERATAS
Di sini Anda akan menetapkan beberapa default dan bersiap untuk mencetaknya saat dipanggil ...
#!/bin/sh
_top_of_script_pr() (
IFS="$nl" ; set -f #only split at newlines and don't expand paths
printf %s\\n ${strings}
) 3<<-TEMPLATES
${nl=
}
${PLACE:="your mother's house"}
${EVENT:="the unspeakable."}
${ACTION:="heroin"}
${RESULT:="succeed."}
${strings:="
I went to ${PLACE} and saw ${EVENT}
If you do ${ACTION} you will ${RESULT}
"}
#END
TEMPLATES
TENGAH
Di sinilah Anda mendefinisikan fungsi lain untuk memanggil fungsi cetak Anda berdasarkan hasil mereka ...
EVENT="Disney on Ice."
_more_important_function() { #...some logic...
[ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
_top_of_script_pr
}
_less_important_function() { #...more logic...
one=2
: "${ACTION:="calligraphy"}"
_top_of_script_pr
}
BAWAH
Anda telah menyiapkan semuanya sekarang, jadi di sinilah Anda akan menjalankan dan menarik hasil Anda.
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
HASIL
Saya akan membahas mengapa suatu saat, tetapi menjalankan di atas menghasilkan hasil sebagai berikut:
_less_important_function()'s
Lari pertama:
Saya pergi ke rumah ibumu dan melihat Disney on Ice.
Jika Anda melakukan kaligrafi, Anda akan berhasil.
kemudian _more_important_function():
Saya pergi ke kuburan dan melihat Disney on Ice.
Jika Anda melakukan matematika perbaikan Anda akan berhasil.
_less_important_function()
lagi:
Saya pergi ke kuburan dan melihat Disney on Ice.
Jika Anda melakukan matematika perbaikan Anda akan menyesalinya.
BAGAIMANA ITU BEKERJA:
Fitur utama di sini adalah konsep conditional ${parameter} expansion.
Anda dapat mengatur variabel ke nilai hanya jika tidak disetel atau null menggunakan formulir:
${var_name
: =desired_value}
Jika Anda hanya ingin menetapkan variabel yang tidak disetel, Anda akan menghilangkan :colon
dan nilai-nilai nol akan tetap apa adanya.
TENTANG RUANG LINGKUP:
Anda mungkin memperhatikan bahwa dalam contoh di atas $PLACE
dan $RESULT
diubah ketika diatur melalui parameter expansion
meskipun _top_of_script_pr()
telah dipanggil, mungkin pengaturan mereka ketika dijalankan. Alasan karya ini adalah bahwa _top_of_script_pr()
adalah ( subshelled )
fungsi - Saya sertakan dalam parens
daripada { curly braces }
yang digunakan untuk orang lain. Karena itu disebut dalam subkulit, setiap variabel yang disetel adalah locally scoped
dan saat ia kembali ke shell induknya, nilai-nilai itu menghilang.
Tetapi ketika _more_important_function()
set $ACTION
itu globally scoped
begitu mempengaruhi _less_important_function()'s
evaluasi kedua $ACTION
karena _less_important_function()
set $ACTION
hanya melalui${parameter:=expansion}.
:BATAL
Dan mengapa saya menggunakan :colon?
Yah terkemuka , man
halaman akan memberitahu Anda bahwa : does nothing, gracefully.
Anda lihat, parameter expansion
persis seperti apa kedengarannya - itu expands
dengan nilai ${parameter}.
Jadi ketika kita mengatur variabel dengan ${parameter:=expansion}
kita pergi dengan nilainya - yang shell akan upaya untuk mengeksekusi in-line. Jika ia mencoba menjalankannya, the cemetery
ia hanya akan meludahkan beberapa kesalahan pada Anda. PLACE="${PLACE:="the cemetery"}"
akan menghasilkan hasil yang sama, tetapi juga berlebihan dalam hal ini dan saya lebih suka shell: ${did:=nothing, gracefully}.
Itu memungkinkan Anda untuk melakukan ini:
echo ${var:=something or other}
echo $var
something or other
something or other
DI SINI-DOKUMEN
Dan omong-omong - definisi in-line dari variabel nol atau tidak disetel juga mengapa yang berikut ini berfungsi:
<<HEREDOC echo $yo
${yo=yoyo}
HEREDOC
yoyo
Cara terbaik untuk memikirkan here-document
adalah sebagai file aktual yang dialirkan ke file-deskriptor input. Kurang lebih seperti itu, tetapi cangkang yang berbeda menerapkannya sedikit berbeda.
Dalam kasus apa pun, jika Anda tidak mengutip, <<LIMITER
Anda dapat mengalirkannya dan mengevaluasi untuk expansion.
Jadi mendeklarasikan variabel dalam sebuah here-document
can dapat berfungsi, tetapi hanya melalui expansion
yang membatasi Anda untuk menetapkan hanya variabel yang belum ditetapkan. Namun, itu sangat sesuai dengan kebutuhan Anda seperti yang telah Anda gambarkan, karena nilai default Anda akan selalu ditetapkan ketika Anda memanggil fungsi cetak template Anda.
KENAPA TIDAK eval?
Nah, contoh yang saya sajikan memberikan cara yang aman dan efektif untuk menerima parameters.
Karena menangani ruang lingkup, setiap variabel dalam set via ${parameter:=expansion}
dapat didefinisikan dari luar. Jadi, jika Anda meletakkan semua ini dalam skrip yang disebut template_pr.sh dan jalankan:
% RESULT=something_else template_pr.sh
Anda akan mendapatkan:
Saya pergi ke rumah ibumu dan melihat Disney on Ice
Jika Anda melakukan kaligrafi, Anda akan melakukan sesuatu
Saya pergi ke kuburan dan melihat Disney on Ice
Jika Anda melakukan perbaikan matematika Anda akan something_else
Saya pergi ke kuburan dan melihat Disney on Ice
Jika Anda melakukan perbaikan matematika Anda akan something_else
Ini tidak akan berfungsi untuk variabel-variabel yang secara harfiah diatur dalam skrip, seperti $EVENT, $ACTION,
dan$one,
tetapi saya hanya mendefinisikan mereka dengan cara itu untuk menunjukkan perbedaannya.
Dalam kasus apa pun, penerimaan input yang tidak diketahui ke dalam suatu evaled
pernyataan pada dasarnya tidak aman, sedangkan parameter expansion
secara khusus dirancang untuk melakukannya.