我想用更自上而下的设计编写一个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 =
通往阅读的管道根本不起作用。让我们作为来尝试一下,这里是阅读:
#!/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中认为的那样工作?或者有更好的方法吗?
您必须引用:
#!/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脚本所示,从stdin管道读取值:
$ 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
如果不使用read,这也将在bash
和ksh
:中工作
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"