bash从函数中设置多个变量的方法

时间:2014-02-11 18:16:23

标签: bash function

我想在更顶级的设计中编写一个shell脚本。我习惯用Kornshell脚本来做这件事。我定义了可能返回多组变量的各种函数(例如,getopts函数)。然后我可以在我的主程序中使用这些函数来设置我想要的变量。

不幸的是,BASH和Kornshell似乎在处理这个实例的方式上存在分歧。这是我在Kornshell中运行的一个简单脚本。我的函数foo返回四个值。我将把这四个值读入主程序中的变量:

#!/bin/ksh

function foo {
    echo "this:that:the:other"
}

IFS=":"
foo | read one two three four
echo "one = $one"
echo "two = $two"
echo "three = $three"
echo "four = $four"

这会产生:

one = this
two = that
three = the
four = other

像魅力一样工作。让我们使用BASH而不是Kornshell尝试相同的程序:

#!/bin/bash

function foo {
    echo "this:that:the:other"
}

IFS=":"
foo | read one two three four
echo "one = $one"
echo "two = $two"
echo "three = $three"
echo "four = $four"

这会产生:

one = 
two = 
three = 
four = 

读取的管道根本不起作用。让我们尝试将其作为 hereis 阅读:

#!/bin/bash

function foo {
    echo "this:that:the:other"
}

IFS=":"
read one two three four<<<$(foo)
echo "one = $one"
echo "two = $two"
echo "three = $three"
echo "four = $four"

我明白了:

one = this that the other
two =
three =
four =

允许设置$one,但不允许设置其他变量。奇怪的是,冒号从字符串中删除。让我们从返回值中删除冒号:

#!/bin/bash

function foo {
    echo "this that the other"
}

read  one two three four<<<$(foo)
echo "one = $one"
echo "two = $two"
echo "three = $three"
echo "four = $four"

one = this
two = that
three = the
four = other

这确实有效。从函数foo读入每个变量。

我做错了什么?为什么设置IFS似乎不像我认为的那样在BASH中工作?或者有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

你必须引用:

#!/bin/bash

function foo {
    echo "this:that:the:other"
}

IFS=":"
read one two three four<<<"$(foo)"
                          ^      ^

执行时返回:

$ ./a
one = this
two = that
three = the
four = other

关于这个不起作用:

#!/bin/bash

...    

IFS=":"
foo | read one two three four
echo "one = $one"

我想这是因为IFS定义在与read不同的shell中。另外,将foo传递给read似乎不是在bash中为read提供字符串的方式。

为此,打开一个新的shell,如Bash script, read values from stdin pipe所示:

$ foo | { IFS=":"; read one two three four; echo "one = $one"; echo "two = $two"; echo "three = $three"; echo "four = $four"; }
one = this
two = that
three = the
four = other

答案 1 :(得分:1)

不使用阅读,这也适用于bashksh

IFS=: && set -- `foo`
echo "one = $1"
echo "two = $2"
echo "three = $3"
echo "four = $4"

bts这也适用于BASH而不创建子shell:

function foo {
    echo "this:that:the:other"
}

IFS=":" read one two three four < <(foo)
echo "one = $one"
echo "two = $two"
echo "three = $three"
echo "four = $four"