我对bash脚本感到困惑。

我有以下代码:

function grep_search() {
    magic_way_to_define_magic_variable_$1=`ls | tail -1`
    echo $magic_variable_$1
}

我希望能够创建一个变量名,其中包含命令的第一个参数,并承载例如ls的最后一行的值。

为了说明我想要的:

$ ls | tail -1
stack-overflow.txt

$ grep_search() open_box
stack-overflow.txt

那么,我应该如何定义/声明$magic_way_to_define_magic_variable_$1,我应该如何在脚本中调用它?

我已经试过eval, ${…}, \$${...},但我还是很困惑。


当前回答

虽然我认为声明-n仍然是最好的方法,但还有另一种没有人提到的方法,在CI/CD中非常有用

function dynamic(){
  export a_$1="bla"
}

dynamic 2
echo $a_2

此函数不支持空格,因此动态“2 3”将返回错误。

其他回答

使用关联数组,命令名作为键。

# Requires bash 4, though
declare -A magic_variable=()

function grep_search() {
    magic_variable[$1]=$( ls | tail -1 )
    echo ${magic_variable[$1]}
}

如果你不能使用关联数组(例如,你必须支持bash 3),你可以使用declare来创建动态变量名:

declare "magic_variable_$1=$(ls | tail -1)"

并使用间接参数展开来访问该值。

var="magic_variable_$1"
echo "${!var}"

参见BashFAQ:间接-计算间接/引用变量。

对于索引数组,你可以像这样引用它们:

foo=(a b c)
bar=(d e f)

for arr_var in 'foo' 'bar'; do
    declare -a 'arr=("${'"$arr_var"'[@]}")'
    # do something with $arr
    echo "\$$arr_var contains:"
    for char in "${arr[@]}"; do
        echo "$char"
    done
done

关联数组可以类似地引用,但需要在declare上使用-A开关而不是-A。

哇,大部分语法都很糟糕!如果你需要间接引用数组,这里有一个简单语法的解决方案:

#!/bin/bash

foo_1=(fff ddd) ;
foo_2=(ggg ccc) ;

for i in 1 2 ;
do
    eval mine=( \${foo_$i[@]} ) ;
    echo ${mine[@]}" " ;
done ;

对于更简单的用例,我推荐使用高级bash脚本编写指南中描述的语法。

根据BashFAQ/006,你可以使用read with here字符串语法来分配间接变量:

function grep_search() {
  read "$1" <<<$(ls | tail -1);
}

用法:

$ grep_search open_box
$ echo $open_box
stack-overflow.txt

对于varname=$prefix_suffix格式,只需使用:

varname=${prefix}_suffix