Saya bekerja dengan bash script dan saya ingin menjalankan fungsi untuk mencetak kembali nilai:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Ketika saya mengeksekusi fun2
, itu tidak mencetak "34". Mengapa hal ini terjadi?
Meskipun bash telah kembali
pernyataan, satu-satunya hal yang dapat anda tentukan dengan itu adalah fungsi's sendiri keluar
status (nilai antara 0
dan 255
, 0 yang berarti "sukses"). Jadi kembali
ini bukan apa yang anda inginkan.
Anda mungkin ingin mengubah anda kembali
pernyataan untuk sebuah echo
pernyataan - dengan cara itu anda fungsi output bisa ditangkap dengan menggunakan $()
kawat gigi, yang tampaknya menjadi apa yang anda inginkan.
Berikut ini sebuah contoh:
function fun1(){
echo 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Cara lain untuk mendapatkan kembali nilai (jika anda hanya ingin mengembalikan integer 0-255) adalah $?
.
function fun1(){
return 34
}
function fun2(){
fun1
local res=$?
echo $res
}
Juga, perhatikan bahwa anda dapat menggunakan kembali nilai untuk menggunakan logika boolean seperti fun1 || fun2
hanya akan menjalankan fun2
jika fun1
kembali 0
nilai. Default nilai kembali adalah nilai keluar dari pernyataan terakhir yang dieksekusi di dalam fungsi.
$(...)
menangkap teks yang dikirim ke stdout oleh perintah yang terkandung di dalamnya. kembali
tidak output ke stdout. $?
berisi kode hasil dari perintah terakhir.
fun1 (){
return 34
}
fun2 (){
fun1
local res=$?
echo $res
}
Fungsi di Bash tidak fungsi seperti dalam bahasa lain; mereka're sebenarnya perintah. Jadi fungsi-fungsi yang digunakan seolah-olah mereka binari atau script yang diambil dari jalan anda. Dari perspektif dari logika program yang ada harus benar-benar tidak ada perbedaan.
Perintah Shell yang dihubungkan dengan pipa-pipa (alias aliran), dan tidak mendasar atau user-defined data types, seperti di "nyata" bahasa pemrograman. Tidak ada hal seperti itu seperti kembali nilai untuk perintah, mungkin sebagian besar karena ada's tidak ada cara nyata untuk menyatakan hal itu. Itu bisa terjadi pada pria-halaman, atau --help
output dari perintah, tetapi keduanya hanya dapat dibaca manusia dan karenanya ditulis untuk angin.
Ketika perintah yang ingin mendapatkan masukan-masukan itu membaca dari input stream, atau daftar argumen. Dalam kedua kasus string teks harus diurai.
Ketika perintah yang ingin kembali sesuatu yang telah echo
ke output stream. Lain sering dipraktekkan cara adalah untuk menyimpan return value dalam berdedikasi, global variabel. Menulis ke output stream yang lebih jelas dan lebih fleksibel, karena dapat mengambil juga data biner. Misalnya, anda dapat kembali GUMPALAN dengan mudah:
encrypt() {
gpg -c -o- $1 # encrypt data in filename to stdout (asks for a passphrase)
}
encrypt public.dat > private.dat # write function result to file
Seperti yang telah ditulis orang lain di thread ini, pemanggil dapat juga menggunakan perintah substitusi $()
untuk menangkap output.
Parallely, fungsi akan "kembalikan" kode keluar dari gpg
(GnuPG). Pikirkan kode keluar sebagai bonus yang lain bahasa don't memiliki, atau, tergantung pada temperamen, sebagai "Schmutzeffekt" fungsi shell. Status ini, dengan konvensi, 0 pada keberhasilan atau integer dalam range 1-255 untuk sesuatu yang lain. Untuk membuat ini jelas: return
(seperti keluar
) hanya dapat mengambil nilai dari 0-255, dan nilai-nilai lain dari 0 belum tentu kesalahan, seperti yang sering menegaskan.
Ketika anda don't memberikan eksplisit nilai dengan return
status ini diambil dari perintah terakhir yang di Bash pernyataan/fungsi/perintah dan sebagainya. Jadi selalu ada status, dan kembali
adalah cara mudah untuk memberikan itu.
Kembali
pernyataan set kode keluar dari fungsi, sama seperti keluar
akan lakukan untuk seluruh naskah.
Kode keluar untuk perintah terakhir selalu tersedia di $?
variabel.
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $? # <-- Always echos 0 since the 'local' command passes.
res=$(fun1)
echo $? #<-- Outputs 34
}
Masalah dengan jawaban lainnya adalah mereka juga menggunakan global, yang dapat ditimpa ketika beberapa fungsi dalam panggilan rantai, atau echo
yang berarti fungsi anda tidak dapat output info diagnostik (anda akan lupa anda fungsi ini dan "hasil", yaitu nilai kembali, akan mengandung lebih banyak info dari pemanggil anda mengharapkan, menyebabkan bug yang aneh), atau eval
yang terlalu berat dan hacky.
Cara yang tepat untuk melakukan ini adalah untuk menempatkan tingkat atas barang-barang dalam fungsi dan menggunakan lokal
dengan bash's dinamis scoping aturan. Contoh:
func1()
{
ret_val=hi
}
func2()
{
ret_val=bye
}
func3()
{
local ret_val=nothing
echo $ret_val
func1
echo $ret_val
func2
echo $ret_val
}
func3
Ini output
nothing
hi
bye
Dinamis pelingkupan berarti bahwa ret_val
poin untuk objek yang berbeda tergantung pada pemanggil! Ini berbeda dari leksikal scoping, yang adalah apa yang kebanyakan bahasa pemrograman yang digunakan. Ini adalah benar-benar fitur didokumentasikan, hanya mudah untuk kehilangan, dan tidak menjelaskan dengan sangat baik, berikut ini merupakan dokumentasi untuk itu (penekanan saya):
Variabel lokal fungsi dapat dinyatakan dengan lokal builtin. Variabel-variabel tersebut terlihat hanya untuk fungsi dan perintah itu memanggil.
Untuk seseorang dengan C/C++/Python/Java/C#/javascript latar belakang, ini mungkin adalah rintangan terbesar: fungsi di bash tidak fungsi, mereka perintah-perintah, dan berperilaku seperti itu: mereka dapat output ke stdout
/stderr
, mereka dapat pipe in/out, mereka dapat kembali kode keluar. Pada dasarnya tidak ada perbedaan antara mendefinisikan perintah dalam suatu script dan menciptakan sebuah executable yang dapat dipanggil dari command line.
Jadi alih-alih menulis script seperti ini:
top-level code
bunch of functions
more top-level code
menulis itu seperti ini:
# define your main, containing all top-level code
main()
bunch of functions
# call main
main
di mana main()
menyatakan ret_val
sebagai lokal
dan semua fungsi lainnya kembali nilai-nilai melalui ret_val
.
Lihat juga berikut Unix & Linux pertanyaan: Cakupan Variabel Lokal dalam Shell Functions.
Lain, bahkan mungkin solusi yang lebih baik tergantung pada situasi, adalah salah satu diposting oleh ya.teck yang menggunakan lokal -n
.
Saya ingin melakukan hal berikut ini jika dijalankan dalam script yang mana fungsi ini didefinisikan:
POINTER= # used for function return values
my_function() {
# do stuff
POINTER="my_function_return"
}
my_other_function() {
# do stuff
POINTER="my_other_function_return"
}
my_function
RESULT="$POINTER"
my_other_function
RESULT="$POINTER"
Saya suka ini, karena saya kemudian dapat mencakup echo pernyataan dalam fungsi saya jika saya ingin
my_function() {
echo "-> my_function()"
# do stuff
POINTER="my_function_return"
echo "<- my_function. $POINTER"
}
Sebagai add-on untuk orang lain' baik posting, di sini's sebuah artikel yang merangkum teknik-teknik ini:
Git Bash di Windows menggunakan array untuk beberapa kembali nilai-nilai
BASH KODE:
#!/bin/bash
##A 6-element array used for returning
##values from functions:
declare -a RET_ARR
RET_ARR[0]="A"
RET_ARR[1]="B"
RET_ARR[2]="C"
RET_ARR[3]="D"
RET_ARR[4]="E"
RET_ARR[5]="F"
function FN_MULTIPLE_RETURN_VALUES(){
##give the positional arguments/inputs
##$1 and $2 some sensible names:
local out_dex_1="$1" ##output index
local out_dex_2="$2" ##output index
##Echo for debugging:
echo "running: FN_MULTIPLE_RETURN_VALUES"
##Here: Calculate output values:
local op_var_1="Hello"
local op_var_2="World"
##set the return values:
RET_ARR[ $out_dex_1 ]=$op_var_1
RET_ARR[ $out_dex_2 ]=$op_var_2
}
echo "FN_MULTIPLE_RETURN_VALUES EXAMPLES:"
echo "-------------------------------------------"
fn="FN_MULTIPLE_RETURN_VALUES"
out_dex_a=0
out_dex_b=1
eval $fn $out_dex_a $out_dex_b ##<--Call function
a=${RET_ARR[0]} && echo "RET_ARR[0]: $a "
b=${RET_ARR[1]} && echo "RET_ARR[1]: $b "
echo
##----------------------------------------------##
c="2"
d="3"
FN_MULTIPLE_RETURN_VALUES $c $d ##<--Call function
c_res=${RET_ARR[2]} && echo "RET_ARR[2]: $c_res "
d_res=${RET_ARR[3]} && echo "RET_ARR[3]: $d_res "
echo
##----------------------------------------------##
FN_MULTIPLE_RETURN_VALUES 4 5 ##<---Call function
e=${RET_ARR[4]} && echo "RET_ARR[4]: $e "
f=${RET_ARR[5]} && echo "RET_ARR[5]: $f "
echo
##----------------------------------------------##
read -p "Press Enter To Exit:"
OUTPUT YANG DIHARAPKAN:
FN_MULTIPLE_RETURN_VALUES EXAMPLES:
-------------------------------------------
running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[0]: Hello
RET_ARR[1]: World
running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[2]: Hello
RET_ARR[3]: World
running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[4]: Hello
RET_ARR[5]: World
Press Enter To Exit: