bash从函数设置多个变量的方式 [英] bash way of setting multiple variables from a function

查看:127
本文介绍了bash从函数设置多个变量的方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

 #!/ bin / ksh 

函数foo {
echothis:that:the:other
}

IFS =:
foo |阅读一个两个三四
回声一= $一
回声二= $二
回声三= $三
回声四= $四

这产生:

  one = this 
two = that
three =
four = other

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

 #!/ bin / bash 

函数foo {
echothis:that:the:other
}

IFS =:
foo |阅读一个两个三四
回声一= $一
回声二= $二
回声三= $三
回声四= $四

这产生:

  one = 
two =
three =
four =

读取的管道根本不起作用。让我们试试这个 hereis 阅读:

 #!/ bin / bash 

函数foo {
echothis:that:other:
}

IFS =:
读取一个两个三个四个<< < $(foo)
echoone = $ one
echotwo = $ two
echothree = $ three
echofour = $ four

我得到:

  one =这表示其他
two =
three =
four =

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

 #!/ bin / bash 

function foo {
echothis that the other
}

read one two three four <<< $(foo)
echoone = $ one
echotwo = $ two
echothree = $ three
echofour = $ four

one = this
two = that
three =
four = other

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



我做错了什么?为什么不设置 IFS 似乎按照我认为在BASH中的方式工作?或者有更好的方法来做到这一点?

解决方案

您必须引用:

 #!/ bin / bash 

函数foo {
echothis:that:the:other
}

IFS =:
读取一二三四<<<$(foo)
^ ^



执行时会返回:

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






关于这个不起作用:

 # !/ bin / bash 

...

IFS =:
foo |阅读一二三四
echoone = $ one

我想这是因为 IFS 定义在与 read 不同的shell中。此外,管 foo read 似乎不是将字符串赋给<$ c $在bash中读取



为此,请打开一个新shell,如 bash脚本,从标准输入管道读取值

  $ foo | {IFS =:;读一两三四;回声一=一美元;回声two = $ 2;回声三=三美元;回声四=四美元; } 
one = this
two = that
three =
four = other


I want to write a shell script in a more top downish design. I've use to do this with Kornshell scripts. I define various functions that may return multiple set of variables (for example, a getopts function). I can then use these functions in my main program to set the variables I want.

Unfortunately, BASH and Kornshell seem to diverge in the way they handle this instance. Here's a simple script I run in the Kornshell. My function foo returns four values. I'll read in these four values into variables in my main program:

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

This produces:

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

Works like a charm. Let's try the same program using BASH instead of 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"

This produces:

one = 
two = 
three = 
four = 

The pipe to the read doesn't work at all. Let's try this as a hereis read:

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

I get:

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

That allowed $one to be set, but not the other variables. Strangely, the colons were removed from the string. Let's remove the colons from the return value:

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

That does work. Each variable is read in from function foo.

What am I doing wrong? Why doesn't setting IFS seem to work the way I would think it would in BASH? Or is there a better way to do this?

解决方案

You have to quote:

#!/bin/bash

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

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

When executed it returns:

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


Regarding this one not working:

#!/bin/bash

...    

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

I guess it is because IFS is defined in a different shell than the one having read. Also, to pipe foo to read doesn't seem to be the way to give a string to read in bash.

To do it, open a new shell, as seen on 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

这篇关于bash从函数设置多个变量的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆