2012-08-01 60 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倍)。