bash通过引用间接引用

时间:2013-08-24 03:34:06

标签: bash variables

很多类似的问题,但没有找到一个在名称中使用变量的方式:

#!/bin/bash

# $1 should be 'dev' or 'stg'

dev_path="/path/to/123"
stg_path="/path/to/xyz"

# Use $1 as input to determine which path variable to 'execute'
${!\$1'/morepath'}

使用$ 1,我希望能够引用$ dev_path或$ stg_path($ 1 =='dev'或$ 1 =='stg')并且能够引用$ 1_path的值,这将是'/ path / to / 123'或'/ path / to / xyz'

所以结果可能是:

'/path/to/123/morepath' or '/path/to/xyz/morepath'

基于$ 1为'dev'或'stg'。

我尝试了各种迭代!和\ $在其他帖子的各个地方,但没有运气

3 个答案:

答案 0 :(得分:6)

请参阅shell parameter expansion上的Bash手册部分:

  

如果参数的第一个字符是感叹号(!),则引入一个变量间接的级别。 Bash使用从参数的其余部分形成的变量的值作为变量的名称;然后展开此变量,并在替换的其余部分中使用该值,而不是参数本身的值。这称为indirect expansion。例外情况是下文所述${!prefix }${!name[@]}的扩展。感叹号必须紧跟左支撑,以引入间接。

     

[...]

由于您还希望在再次展开之前修改名称(通过后缀_path),您需要浏览另一个变量:

# $1 should be 'dev' or 'stg'
dev_path="/path/to/dev"
stg_path="/path/to/stg"

path=${1}_path   # path is now either 'dev_path' or 'stg_path'

# Run either /path/to/dev or /path/to/stg
${!path}/bin/execute

当然,如果devstg程序都在同一个目录中,那么就不需要所有这些,你可以直接展开$1

/path/to/$1/bin/execute

答案 1 :(得分:3)

我认为这样会不安全。如果$1获得的值不是dev或stg,则会导致语法错误,并且可能会发生其他意外情况。即使使用eval,除非添加条件过滤器,否则不是一个好主意。您可以使用case语句:

case "$1" in
dev)
    "$dev_path"/bin/execute
    ;;
std)
    "$std_path"/bin/execute
    ;;
*)
    echo "Invalid argument: $1"
    ;;
esac

或确保它有效并使用eval:

[[ $1 == dev || $1 == std ]] && eval "\"\${${1}_path}/bin/execute\""

使用if ... elif ...也可能有效,但case方法更简单。

对于variable indirection,您需要先将"${1}_path"存储到另一个变量中,这是不必要的。

您也可以根据自己的喜好在dev|std) eval ... ;;语句中使用case

答案 2 :(得分:0)

为什么需要“变量,变量”?为什么不

MYPATH="/path/to/$1"
$MYPATH/bin/execute