2013-06-27 105 views
134

返回值我有一個bash腳本的工作,我想執行一個功能打印返回值:在bash腳本

function fun1(){ 
    return 34 
} 
function fun2(){ 
    local res=$(fun1) 
    echo $res 
} 

當我執行fun2,它不打印「34」。爲什麼會這樣?

+5

你的情況下的'return'與'0-255'範圍內的退出代碼基本相同。按@septi建議使用'echo'。退出代碼可以用'$?'來捕獲。 – devnull

+0

在這種情況下,已經在fun1中使用echo更加靈活。這是unix編程的思想:echo將結果發送到標準輸出,然後可以通過res = $(fun1)的其他函數重新使用結果 - 或者直接傳遞給其他函數:'function a(){echo 34; }''函數b(){讀取數據時;做echo $ data;完成;}''a | b' –

回答

185

雖然bash有一個return語句,但您可以用它指定的唯一東西是函數自己的exit狀態(0到255之間的值,0表示「成功」)。所以return不是你想要的。

您可能希望將return語句轉換爲echo語句 - 這樣可以使用$()括號來捕獲您的函數輸出,這似乎正是您想要的。

下面是一個例子:

function fun1(){ 
    echo 34 
} 

function fun2(){ 
    local res=$(fun1) 
    echo $res 
} 

另一種方式來獲得的返回值(如果你只是想返回一個整數0-255)是$?

function fun1(){ 
    return 34 
} 

function fun2(){ 
    fun1 
    local res=$? 
    echo $res 
} 

另外請注意,您可以使用返回值來使用布爾邏輯一樣fun1 || fun2將只運行FUN2如果FUN1返回一個0值。默認返回值是函數內執行的最後一個語句。

+0

謝謝,但我想使用return.How我可以得到價值嗎?在這種情況下 – mindia

+2

您需要執行'fun1',然後返回值存儲在'$?'中。雖然我不會推薦這麼做...... – tamasgal

+4

'+ 1'不直接暗示'$?'。 – devnull

40

$(...)捕獲通過內部命令發送到標準輸出的文本。 return不輸出到標準輸出。 $?包含最後一個命令的結果代碼。

fun1(){ 
    return 34 
} 

fun2(){ 
    fun1 
    local res=$? 
    echo $res 
} 
+0

和'return'是一個'result'代碼? – Blauhirn

+1

是'return'用於設置'$?'這是'退出狀態'。在上面的例子中,fun1的退出狀態是'34'。另外請注意,'$(...)'除捕獲指定命令的stdout外,還捕獲stderr。 – swoop81

13

return語句設置功能的退出代碼,一樣一樣exit將整個腳本做。

最後一條命令的退出代碼始終可用於$?變量。

function fun1(){ 
    return 34 
} 

function fun2(){ 
    local res=$(fun1) 
    echo $? # <-- Always echos 0 since the 'local' command passes. 

    res=$(fun1) 
    echo $? #<-- Outputs 34 
} 
23

Bash中的函數不像其他語言的函數;他們實際上是命令。所以函數就像是從路徑中獲取的二進制文件或腳本一樣使用。從程序邏輯的角度來看,應該沒有什麼區別。

Shell命令通過管道(aka streams)連接,而不是像「真正的」編程語言那樣基本或用戶定義的數據類型。沒有像命令返回值那樣的東西,可能主要是因爲沒有真正的方法來聲明它。它可能出現在手冊頁或命令的輸出中,但兩者都只是人類可讀的,因此被寫下來。

當命令想要獲得輸入時,它從輸入流或參數列表中讀取它。在這兩種情況下,文本字符串都必須被解析。

當某個命令想要返回某個內容時,它必須將其echo轉換爲其輸出流。另一種常用的方法是將返回值存儲在專用的全局變量中。寫入輸出流更清晰且更靈活,因爲它也可以採用二進制數據。例如,您可以輕鬆地返回BLOB:

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 

正如其他人寫在這個線程,調用者也可以使用命令替換$()捕獲輸出。

同時,該函數將「返回」gpg(GnuPG)的退出代碼。把退出代碼想象成其他語言沒有的獎勵,或者根據你的氣質,作爲shell函數的「Schmutzeffekt」。按照慣例,這種狀態在成功時爲0,或者在1-255範圍內的其他值爲整數。爲了清楚起見:return(如exit)只能取0-255之間的一個值,非0之外的值不一定是錯誤,正如經常聲明的那樣。

當你沒有提供明確的值return狀態取自Bash語句/函數/命令中的最後一個命令等等。所以總是有一個狀態,return只是一個簡單的方法來提供它。

3

我喜歡做以下,如果在該函數定義腳本運行時間:

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" 

我喜歡這個,becase的然後我就可以包括在我的函數echo語句,如果我想

my_function() { 
    echo "-> my_function()" 
    # do stuff 
    POINTER="my_function_return" 
    echo "<- my_function. $POINTER" 
} 
-1

的Git上猛砸的Windows使用數組爲多個返回值

bash代碼:

#!/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:" 

預期輸出:

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: