使用shell变量选择一个bash数组

时间:2015-01-27 23:40:27

标签: arrays bash shell pointers reference

我正在尝试编写一个bash脚本,允许我在一组不同的数组中选择一个数组。为此,我打算使用一个简单的变量来引用那个数组。

#!/bin/bash
#To get all the members of a given array as the output
#variables
FIRST=(A B C D)
SECOND=(planes cars trains bicycles gocarts)
THIRD=(werewolfs vampires zombies ghosts daemons)
FOURTH=(football soccer basketball rugby batmington zumo)
FIFTH=(handguns rifles machineguns bazookas slingshots)
SIXTH=(dogs cats turtles ferrets birds hamsters fish)
SEVENTH=(monday tuesday wednesday thursday friday saturday sunday)

#execution
select ARRAY in "FIRST" "SECOND" "THIRD" "FOURTH" "FIFTH" "SIXTH" "SEVENTH"; do 
    OUTPUT=eval '"${'${ARRAY}'[@]}"'
    echo $OUTPUT
    break 
done

#end

以上脚本不起作用。到目前为止,我已尝试用以下选项替换第9行

OUTPUT=eval '$'{ARRAY'[@]'}
OUTPUT=eval ${"$ARRAY"[@]}
OUTPUT=eval ${'$ARRAY'[@]}
OUTPUT=eval ${'$'ARRAY[@]}
OUTPUT=eval '$'{"$ARRAY"[@]}
OUTPUT=eval \${${ARRAY}[@]}

我在这里缺少什么?

3 个答案:

答案 0 :(得分:1)

这对我有用:

#!/bin/bash
#To get all the members of a given array as the output
#variables
FIRST=(A B C D)
SECOND=(planes cars trains bicycles gocarts)
THIRD=(werewolfs vampires zombies ghosts daemons)
FOURTH=(football soccer basketball rugby batmington zumo)
FIFTH=(handguns rifles machineguns bazookas slingshots)
SIXTH=(dogs cats turtles ferrets birds hamsters fish)
SEVENTH=(monday tuesday wednesday thursday friday saturday sunday)

#execution
ARRAY="FIFTH"
select ARRAY in "FIRST" "SECOND" "THIRD" "FOURTH" "FIFTH" "SIXTH" "SEVENTH"; do
    eval "OUTPUT=\${$ARRAY[*]}"
    echo $OUTPUT
    break
done

eval可用于引入新变量。我们构造一个字符串,其中包含将所需值分配给OUTPUT的表达式,然后对其进行评估,从而引入一个具有所需值的新变量OUTPUT

答案 1 :(得分:1)

eval绝对没有必要解决这个问题。在使用eval之前,您应该始终三思,因为它的脆弱性。 (也就是说,错误会带来灾难性的后果。)

这是“传统”解决方案,它使用!间接语法。它仍然有些脆弱,但没有eval那么糟糕:

select array in "FIRST" "SECOND" "THIRD" "FOURTH" "FIFTH" "SIXTH" "SEVENTH"; do
  if [[ $array ]]; then
    # Indirection requires the full subscript to be included
    # in the variable which is used to indirect. "${!array[@]}"
    # would be "0", because that is not indirect syntax; rather it
    # is "array keys" syntax.
    array_at="$array"[@]
    echo "${!array_at}"
    break
  else
    echo "Invalid input; try again" >> /dev/stderr
  fi
done

从bash 4.3开始,你可以使用引用声明,这使得上面的内容不那么笨重了:

select name in "FIRST" "SECOND" "THIRD" "FOURTH" "FIFTH" "SIXTH" "SEVENTH"; do
  if [[ $name ]]; then
    declare -n array=name
    echo "${array[@]}"
    break
  else
    echo "Invalid input; try again" >> /dev/stderr
  fi
done
# Unless the user exits the select by typing an EOF,
# then `array` is now effectively a synonym
# for whichever of the arrays was selected.

答案 2 :(得分:0)

我明白了。 以下适用于第9行

OUTPUT=$(eval echo \${${ARRAY}[@]})

非常感谢你对这个可怜的小学徒的耐心:)