shell脚本中的以下函数只在数组上调用时循环遍历数组的第一个元素,出了什么问题?
#!/bin/sh in_array(){ a=$2 echo ${#a[@]} for (( i = 0; i < ${#a[@]} ; i++ )) do echo ${a[$i]} if [ $1 = ${a[$i]} ] then return 1 fi done return 0 } exclude_dirs=( aaa bbb ) echo ${#exclude_dirs[@]} in_array home $exclude_dirs
答案 0 :(得分:1)
有两个问题。第一个是sh不支持数组,因此你的shebang应该改为shell。 (例如,#!/ bin / bash)。第二个问题更为严重。数组不是bash中的第一类对象(它们可能在其他shell中,但我会回答bash的问题,因为sh经常在许多Linux发行版中出现,而我正在使用我的水晶球来确定你的意思是bash当你说#!/ bin / sh)。您可以使用eval获得所需内容。将您的功能更改为以下内容:
in_array(){ a=$2 eval "for i in \${$a[@]}; do echo \$i test $1 = \$i && return 1 done" return 0 }
并在没有'$'的情况下调用它。
in_array home exclude_dirs
另外,我强烈建议反转返回值。 (如果数组中出现$ 1则返回0,否则返回1)。或者,或者将函数名称更改为“not_it_array”。这将允许您编写如下内容:
if in_array home exclude_dirs; then echo home is excluded; fi
(或使用短路&amp;&amp;)。请记住,在sh中,0表示成功,非零表示失败。
当然,通过传递所有值而不是传递名称来传递数组会更容易:
#!/bin/bash in_array(){ el=$1 shift while test $# -gt 0; do test $el = $1 && return 0 shift done return 1 } exclude_dirs=( aaa home bbb ) in_array home ${exclude_dirs[@]} && echo home is excluded
答案 1 :(得分:0)
William是正确的,你不能在Bourne Shell中使用数组,但你也shouldn't be using eval
。为避免这种情况,您可以简化参数结构:
#!/bin/sh
in_array(){
search_path="$1"
shift
while [ -n "${1+defined}" ]
do
if [ "$1" = "$search_path" ]
then
return 0
fi
shift
done
return 1
}
in_array foo aaa bbb && echo fail test 1
in_array foo foo bar || echo fail test 2
in_array foo bar foo || echo fail test 3
in_array foo foobar && echo fail test 4
in_array foo barfoo && echo fail test 5
in_array foo "foo bar" && echo fail test 6
in_array "foo bar" "foo bar" "baz ban" || echo fail test 7
true