5

我是 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} 那么什么都不会得到回显!请澄清一下。

4

3 回答 3

10

第一个是调用函数并将所有输出(四个echo语句)存储到$constr.

然后,在返回后,您回显序言printing result$constr由四行组成)和退出消息。

这就是$()工作原理,它从封闭的命令中捕获整个标准输出。

听起来您想echo在控制台上查看某些语句,而不是使用$(). 我认为您应该能够将它们发送到标准错误:

echo "String1 $1" >&2
于 2012-08-01T11:39:03.307 回答
1

paxdiablo 的解决方案是正确的。您不能从函数返回字符串,但可以捕获函数的输出或返回一个整数值,调用者可以从$?. 但是,由于所有 shell 变量都是全局变量,您可以简单地执行以下操作:

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

请注意,function关键字与 是多余的(),但function可移植性较差。

于 2012-08-01T14:19:02.177 回答
1

一种更灵活但更难理解的方法是传递一个变量名,并使用eval它使变量在调用者的上下文中设置(全局或本地函数)。在 bash 中:

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

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

    eval "$_varname=\$_t"
}

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

在我的 Linux 桌面(bash-3.2)上,它比 using 快大约 3-5 倍(10,000 次迭代)``,因为后者有进程创建开销。

如果你有 bash-4.2,它declare -g允许一个函数设置一个全局变量,所以你可以将 unpretty 替换为eval

declare -g $_varname="$_t"

eval方法与TCL的 类似upvar 1declare -g也类似upvar #0

一些shell内置支持类似的东西,比如printf带有“-v”的bash,再次通过直接分配给变量而不是捕获输出来保存进程创建(对我来说快了大约20-25倍)。

于 2013-01-09T13:56:27.887 回答