2012-08-01 32 views
4

我是新來的shell腳本,我想創建一個簡單的函數,它將返回連接的兩個字符串作爲參數傳遞。我試着用下面的代碼shell腳本函數返回一個字符串

function getConcatenatedString() { 
     echo "String1 $1" 
     echo "String2 $2" 
     str=$1/$2 
     echo "Concatenated String ${str}" 
     echo "${str}" 
    } 

//我打電話上述功能

constr=$(getConcatenatedString "hello" "world") 
    echo "printing result" 
    echo "${constr}" 
    echo "exit" 

我看到運行上面的代碼腳本時下面的輸出,

printing result 
    String1 hello 
    String2 world 
    Concatenated String hello/world 
    hello/world 
    exit 

如果你看看在代碼中,我首先調用函數,然後回顯「打印結果」語句,但結果首先出現「打印結果」並在函數內部回顯語句。在下面的語句調用該函數

constr=$(getConcatenatedString "hello" "world") 

echo ${constr} 

調用函數?

因爲如果我註釋掉#echo $ {constr},那麼沒有什麼會得到迴應!請澄清我。

回答

9

第一個調用函數並將的所有的輸出(四個echo語句)存儲爲$constr

然後,返回後,回顯前導碼printing result,$constr(由四行組成)和退出消息。

這就是$()的工作原理,它捕獲封閉命令的整個標準輸出。

聽起來好像你想在控制檯上看到一些echo聲明,而不是用$()來捕獲它們。我認爲你應該能夠將它們發送到標準錯誤:

echo "String1 $1" >&2 
1

paxdiablo的解決方案是正確的。您不能從函數返回字符串,但可以捕獲該函數的輸出或返回一個可由調用方從$?中檢索的整數值。然而,由於所有shell變量是全局的,你可以簡單地做:

getConcatenatedString() { str="$1/$2"; }  
getConcatenatedString hello world 
echo "Concatenated String ${str}" 

注意,function關鍵字是多餘的(),但function少便攜。

1

一個更靈活,但稍微難以理解的方法是傳遞一個變量名稱,並使用eval以便變量在調用者的上下文(全局或本地函數)中設置。在bash:

function mylist() 
{ 
    local _varname=$1 _p _t 
    shift 

    for _p in "[email protected]"; do 
     _t=$_t[$_p] 
    done 

    eval "$_varname=\$_t" 
} 

mylist tmpvar a b c 
echo "result: $tmpvar" 

在我的Linux桌面(bash的-3.2),這是大約提升3至5快(10,000次迭代)比使用``,因爲後者具有進程創建開銷。

如果你有bash-4。2,其declare -g允許一個函數來設置一個全局變量,所以你可以替換unpretty eval

declare -g $_varname="$_t" 

eval方法類似於TCL'supvar 1,並declare -g類似於upvar #0

一些shell內建支持類似的東西,比如帶有「-v」的bash的printf,通過直接分配給變量而不是捕獲輸出來保存進程創建(對我來說快~20-25倍)。

相關問題