Nilai kembali di Bash fungsi

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?

Mengomentari pertanyaan (3)
Larutan

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.

Komentar (12)

$(...) 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
}
Komentar (2)

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.

Komentar (2)

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 $? # 
Komentar (0)

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.

Komentar (0)

Cara lain untuk mencapai hal ini adalah referensi nama (membutuhkan Bash 4.3+).

function example {
  local -n VAR=$1
  VAR=foo
}

example RESULT
echo $RESULT
Komentar (1)

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 "
Komentar (0)

Sebagai add-on untuk orang lain' baik posting, di sini's sebuah artikel yang merangkum teknik-teknik ini:

  • set variabel global
  • set variabel global, dan nama anda dilewatkan ke fungsi
  • mengatur kembali kode (dan mengambilnya dengan $?)
  • 'echo' beberapa data (dan mengambilnya dengan MYVAR=$(myfunction) )

Kembali nilai-Nilai dari Bash Fungsi

Komentar (0)

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  ##
Komentar (0)