很多类似的问题,但没有找到一个在名称中使用变量的方式:
#!/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'。
我尝试了各种迭代!和\ $在其他帖子的各个地方,但没有运气
答案 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
当然,如果dev
和stg
程序都在同一个目录中,那么就不需要所有这些,你可以直接展开$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