我正在尝试在bash函数中定义一个本地数组,并在该函数外部访问它。
我意识到BASH函数不返回值,但我可以将计算结果分配给全局值。我希望这段代码能够将array []的内容回显到屏幕上。我不确定为什么会失败。
function returnarray
{
local array=(foo doo coo)
#echo "inside ${array[@]}"
}
targetvalue=$(returnarray)
echo ${targetvalue[@]}
答案 0 :(得分:8)
您有两种选择。第一个是@choroba规定的,它可能是最好和最简单的:不要在本地定义你的数组。
returnarray() {
array=(foo doo coo) # NOT local
}
# call your function
returnarray
# now the array is in array and you may copy it for later use as follows:
targetvalue=( "${array[@]}" )
# print it to check:
declare -p targetvalue
这是整洁,简单,安全,完全避免使用子壳(因此它更有效)。但有一点需要注意:它不适用于稀疏数组(但这应该是一个小细节)。还有一个很小的缺点:需要复制数组。
另一种选择是将变量名称传递给函数,并让函数直接生成数组。这使用了namerefs,并且仅在Bash 4.3之后可用(但是如果可以的话,它真的很好用!):
generatearray() {
# $1 is array name in which array is generated
local -n array="$1" || return 1
array=( foo doo coo )
}
# call function that constructs the array with the array name
generatearray targetvalue
# display it
declare -p targetvalue
答案 1 :(得分:2)
要使变量可从外部访问,请不要声明它local
。让它全球化。
答案 2 :(得分:1)
首先,正如您所说,bash函数没有返回值。因此,传递本地值的唯一方法是echo
它。
但是,如果将其解释为数组,这将导致您的targetvalue包含您在索引0中回显的所有内容。要告诉bash将零件视为数组零件,你必须用括号括起来 - 来自bash手册:
将数组分配给使用表单的复合赋值 name =(value1 ... valuen),其中每个值的形式为[sub- 脚本] =字符串。
#!/bin/bash
function returnarray
{
local array=(foo doo coo)
echo "${array[@]}"
}
targetvalue=($(returnarray))
echo ${targetvalue[@]}
echo ${targetvalue[1]}
然而,所有这些都是关于bash
如何工作的编程。最好全局定义数组。
由于使用echo
使bash解释了值,这只有在数组的值不受bash影响的情况下才有效,例如值可能不包含通配符或空格,通配符将扩展为匹配文件和值中的空格将转换为多个数组值。
答案 3 :(得分:0)
看看这个,可能是有空格和其他字符......
#!/bin/bash
function returnarray
{
newname=$1
local array=(foo doo coo)
declare -p array | sed "s/array/$newname/g"
}
eval $(returnarray glob)
echo elm0 ${glob[0]}
echo elm1 ${glob[1]}
echo elm2 ${glob[2]}
请参阅How to return an array in bash without using globals?
编辑:关于'数组'的评论是正确的......这是一个固定版本。 sed 用法我不介意......
#!/bin/bash
function returnarray
{
newname=$1
local array=(foo doo coo "declare -a array" aa)
declare -p array | sed "s/^declare -a array/declare -a $newname/"
}
eval $(returnarray glob)
echo elm0 ${glob[0]}
echo elm1 ${glob[1]}
echo elm2 ${glob[2]}
echo elm2 ${glob[3]}
echo elm2 ${glob[4]}
答案 4 :(得分:0)
您可以声明局部变量,然后printf一个逗号分隔值字符串,它可以很好地转换为数组。关键是使用printf而不是echo。
http://wiki.bash-hackers.org/commands/builtin/read:
使用printf,因为(取决于设置),echo可能会解释一些baskslash-escapes或开关(如-n)。
代码:
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
self.vcToTest = [[TableViewController alloc] init];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
self.vcToTest = [storyboard instantiateViewControllerWithIdentifier:@"testTableView"];
[self.vcToTest performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES];
}
终端:
#Return csv of project.id's
function get_project() {
local qry="select id from ${DB}.projects where identifier=\"${1}\";"
local ids=`sudo -u ${DB_USER} ${DB_LOCATION} -u ${DB_USER} -p${DB_PASS} -s -e "${qry}"`
#return
while read -r element; do printf "%s," "$element"; done <<< "$ids"
}
#Return csv of member.id's
function get_members() {
local qry="select user_id from ${DB}.members where project_id=${1};"
local ids=`sudo -u ${DB_USER} ${DB_LOCATION} -u ${DB_USER} -p${DB_PASS} -s -e "${qry}"`
#return
while read -r element; do printf "%s," "$element"; done <<< "$ids"
}
projects=( $(get_project "newuser1") )
declare -p projects
member_ids=( $(get_members $projects) )
declare -p member_ids