假设我有一个名为“Hello'”的脚本。类似的东西:
array[0]="hello world"
array[1]="goodbye world"
echo ${array[*]}
我想在另一个脚本中做这样的事情:
tmp=(`Hello`)
我需要的结果是:
echo ${tmp[0]} #prints "hello world"
echo ${tmp[1]} #prints "goodbye world"
而不是
echo ${tmp[0]} #prints "hello"
echo ${tmp[1]} #prints "world"
或换句话说,每个单词都放在tmp数组中的不同位置。 我如何得到我需要的结果?
答案 0 :(得分:6)
将其作为NUL分隔的流发送:
printf '%s\0' "${array[@]}"
......而在另一方面,请从该流中读取:
array=()
while IFS= read -r -d '' entry; do
array+=( "$entry" )
done
这通常与过程替换一起派上用场;在下面的示例中,初始代码位于以generate_an_array
调用的命令(无论是函数还是外部进程)中:
array=()
while IFS= read -r -d '' entry; do
array+=( "$entry" )
done < <(generate_an_array)
您还可以使用declare -p
发出一个字符串eval
来获取内容:
array=( "hello world" "goodbye world" )
declare -p array
......而另一方面......
eval "$(generate_an_array)"
然而,这不太可取 - 它不像bash那样可以移植到编程语言(而几乎所有语言都可以读取NUL分隔的流),并且它要求接收程序信任发送程序返回declare -p
结果而非恶意内容。
答案 1 :(得分:2)
虽然有解决方法,但你不能真正从bash函数或脚本“返回”一个数组,因为“返回”一个值的正常方法是将它作为字符串发送到stdout
并让调用者通过命令替换捕获它。 [注1]对于简单的字符串或非常简单的数组(例如数字数组,其中元素不能包含空格),这很好,但它实际上不是发送结构化数据的好方法。
有一些解决方法,例如打印带有特定分隔符(特别是NUL字节)的字符串,可以由调用者解析,或者以可执行bash语句的形式打印,调用者可以使用{{{ 1}},但总的来说,最简单的机制是要求调用者提供可以放置值的数组变量的名称。这仅适用于bash函数,因为脚本不能修改调用者的环境,并且它只适用于父进程中直接调用的函数,因此它不适用于管道。实际上,这是一种类似于eval
内置函数和其他一些read
内置函数的机制。
这是一个简单的例子。函数bash
有三个参数:数组名称,分隔符和字符串:
split
例如:
split () {
IFS=$2 read -a "$1" -r -d '' < <(printf %s "$3")
}
备注:强>
$ # Some text
$ lorem="Lorem ipsum dolor
sit amet, consectetur
adipisicing elit, sed do
eiusmod tempor incididunt"
# Split at the commas, putting the pieces in the array phrase
$ split phrase "," "$lorem"
# Print the pieces in a way that you can see the elements.
$ printf -- "--%s\n" "${phrase[@]}"
--Lorem ipsum dolor
sit amet
-- consectetur
adipisicing elit
-- sed do
eiusmod tempor incididunt
和return
特殊表单实际返回的内容。但是,状态返回主要用作布尔值,当然不能携带结构化值。答案 2 :(得分:1)
declare -a array # declares a global array variable
array=(
"hello world"
"goodbye world"
)
. hello.sh
tmp=( "${array[@]}" ) # if you need to make a copy of the array
echo "${tmp[0]}"
echo "${tmp[1]}"
如果您真的希望函数吐出脚本将捕获的值,请执行以下操作:
#!/bin/bash
array=(
"hello world"
"goodbye world"
)
printf "%s\n" "${array[@]}"
#!/bin/bash
./hello.sh | {
readarray -t tmp
echo "${tmp[0]}"
echo "${tmp[1]}"
}
# or
readarray -t tmp < <(./hello.sh)
echo "${tmp[0]}"
echo "${tmp[1]}"