Saya bekerja dengan skrip bash dan saya ingin menjalankan fungsi untuk mencetak nilai kembali:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Ketika saya mengeksekusi fun2
, itu tidak mencetak "34". Mengapa demikian?
bash
function
return-value
mindia
sumber
sumber
return
dalam kasus Anda pada dasarnya sama denganexit code
yang berkisar dari0 - 255
. Gunakanecho
seperti yang disarankan oleh @septi. Kode keluar dapat ditangkap dengan$?
.function a() { echo 34; }
function b() { while read data; do echo $data ; done ;}
a | b
Jawaban:
Meskipun bash memiliki
return
pernyataan, satu-satunya hal yang dapat Anda tentukan adalah status fungsi itu sendiriexit
(nilai antara0
dan255
, 0 yang berarti "sukses"). Jadireturn
bukan yang Anda inginkan.Anda mungkin ingin mengubah
return
pernyataan Anda menjadiecho
pernyataan - dengan cara itu output fungsi Anda dapat ditangkap menggunakan$()
kurung kurawal, yang tampaknya persis seperti yang Anda inginkan.Berikut ini sebuah contoh:
Cara lain untuk mendapatkan nilai kembali (jika Anda hanya ingin mengembalikan integer 0-255) adalah
$?
.Juga, perhatikan bahwa Anda dapat menggunakan nilai kembali untuk menggunakan logika boolean seperti
fun1 || fun2
hanya akan berjalanfun2
jikafun1
mengembalikan0
nilai. Nilai pengembalian default adalah nilai keluar dari pernyataan terakhir yang dieksekusi dalam fungsi.sumber
fun1
dan kemudian nilai balik disimpan$?
. Meskipun saya tidak akan merekomendasikan untuk melakukan itu ...$?
?||
konstruk ini , kode keluar 0 dianggap sukses dan karenanya "benar". Bukan nol adalah kesalahan dan karenanya salah. Anggapfun1 || fun2
sebagai singkatan untuk "jika fun1 mengembalikan kesuksesan atau fun2 mengembalikan kesuksesan" daripada operator pada nilai pengembalian aktual sendiri.$(...)
menangkap teks yang dikirim ke stdout oleh perintah yang ada di dalamnya.return
tidak menghasilkan stdout.$?
berisi kode hasil dari perintah terakhir.sumber
return
digunakan untuk pengaturan$?
yang merupakanexit status
. Dalam contoh di atas,fun1
'sexit status
akan34
. Juga, perhatikan bahwa$(...)
juga menangkap stderr selain stdout dari perintah yang ditentukan.Fungsi dalam Bash bukan fungsi seperti dalam bahasa lain; mereka sebenarnya perintah. Jadi fungsi digunakan seolah-olah mereka binari atau skrip yang diambil dari jalur Anda. Dari perspektif logika program Anda seharusnya tidak ada perbedaan.
Perintah Shell dihubungkan oleh pipa (alias aliran), dan bukan tipe data dasar atau yang ditentukan pengguna, seperti dalam bahasa pemrograman "nyata". Tidak ada yang namanya nilai pengembalian untuk suatu perintah, mungkin sebagian besar karena tidak ada cara nyata untuk mendeklarasikannya. Itu bisa terjadi pada halaman manual, atau
--help
output dari perintah, tetapi keduanya hanya dapat dibaca oleh manusia dan karenanya ditulis ke angin.Ketika sebuah perintah ingin mendapatkan input, ia membacanya dari aliran inputnya, atau dari daftar argumen. Dalam kedua kasus, string teks harus diuraikan.
Ketika sebuah perintah ingin mengembalikan sesuatu,
echo
ia harus menjalankannya ke aliran outputnya. Cara lain yang sering dilakukan adalah menyimpan nilai pengembalian dalam variabel global khusus. Menulis ke aliran keluaran lebih jelas dan lebih fleksibel, karena dapat juga mengambil data biner. Misalnya, Anda dapat mengembalikan BLOB dengan mudah:Seperti orang lain telah menulis di utas ini, pemanggil juga dapat menggunakan substitusi perintah
$()
untuk menangkap output.Secara paralel, fungsi akan "mengembalikan" kode keluar dari
gpg
(GnuPG). Pikirkan kode keluar sebagai bonus yang tidak dimiliki bahasa lain, atau, tergantung pada temperamen Anda, sebagai "Schmutzeffekt" fungsi shell. Status ini, berdasarkan konvensi, 0 berhasil atau bilangan bulat dalam kisaran 1-255 untuk hal lain. Untuk memperjelas ini:return
(sepertiexit
) hanya dapat mengambil nilai dari 0-255, dan nilai selain 0 tidak selalu merupakan kesalahan, seperti yang sering dinyatakan.Ketika Anda tidak memberikan nilai eksplisit dengan
return
status diambil dari perintah terakhir dalam pernyataan / fungsi / perintah Bash dan sebagainya. Jadi selalu ada status, danreturn
hanya cara mudah untuk menyediakannya.sumber
The
return
pernyataan menetapkan kode keluar dari fungsi, sama sepertiexit
akan melakukan untuk seluruh naskah.Kode keluar untuk perintah terakhir selalu tersedia dalam
$?
variabel.sumber
Masalah dengan jawaban lain adalah mereka menggunakan global, yang dapat ditimpa ketika beberapa fungsi dalam rantai panggilan, atau
echo
yang berarti fungsi Anda tidak dapat menampilkan informasi diagnostik (Anda akan lupa fungsi Anda melakukan ini dan "hasil", yaitu mengembalikan nilai, akan mengandung lebih banyak info dari yang diharapkan penelepon Anda, yang mengarah ke bug aneh), ataueval
yang terlalu berat dan peretasan.Cara yang tepat untuk melakukan ini adalah dengan meletakkan hal-hal tingkat atas dalam suatu fungsi dan menggunakan
local
aturan pelingkupan dinamis dengan bash. Contoh:Ini output
Pelingkupan dinamis berarti
ret_val
menunjuk ke objek yang berbeda tergantung pada pemanggil! Ini berbeda dari pelingkupan leksikal, yang digunakan oleh sebagian besar bahasa pemrograman. Ini sebenarnya adalah fitur yang terdokumentasi , mudah dilewatkan, dan tidak dijelaskan dengan baik, berikut adalah dokumentasi untuk itu (penekanan ada pada saya):Untuk seseorang dengan latar belakang javascript C / C ++ / Python / Java / C # /, ini mungkin merupakan rintangan terbesar: fungsi dalam bash bukan fungsi, mereka adalah perintah, dan berperilaku seperti itu: mereka dapat menampilkan ke
stdout
/stderr
, mereka dapat mengirim pipa ke / out, mereka dapat mengembalikan kode keluar. Pada dasarnya tidak ada perbedaan antara mendefinisikan perintah dalam skrip dan membuat executable yang dapat dipanggil dari baris perintah.Jadi alih-alih menulis skrip Anda seperti ini:
tulis seperti ini:
di mana
main()
menyatakanret_val
sebagailocal
dan semua fungsi lainnya mengembalikan nilai melaluiret_val
.Lihat juga pertanyaan Unix & Linux berikut: Cakupan Variabel Lokal di Fungsi Shell .
Solusi lain, mungkin lebih baik tergantung pada situasinya, adalah solusi yang diposting oleh ya.teck yang menggunakan
local -n
.sumber
Cara lain untuk mencapai ini adalah referensi nama (membutuhkan Bash 4.3+).
sumber
-n <name>=<reference>
dilakukannya: membuat baru dibuat variabel referensi ke satu sama lain ditunjukkan oleh<reference>
. Penugasan lebih lanjut<name>
dilakukan pada variabel yang dirujuk.Saya suka melakukan hal berikut jika menjalankan skrip di mana fungsi didefinisikan:
Saya suka ini, karena saya kemudian dapat memasukkan pernyataan gema dalam fungsi saya jika saya mau
sumber
Sebagai tambahan pada postingan bagus orang lain, inilah artikel yang merangkum teknik ini:
Mengembalikan Nilai dari Fungsi Bash
sumber
Git Bash di Windows menggunakan array untuk beberapa nilai kembali
KODE BASH:
OUTPUT YANG DIHARAPKAN:
sumber