1

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

#!/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”。

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

4

3 回答 3

6

请参阅有关shell 参数扩展的 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
于 2013-08-24T03:41:43.253 回答
3

I think that would be unsafe. If $1 gets a value that's not dev or stg it would cause syntax error and other unexpected things may happen. Even with eval it wouldn't be a good idea unless you add a conditional filter. You could use a case statement:

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

Or make sure it's valid and use eval:

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

Using if ... elif ... could be valid too but the case method is simpler.

As for variable indirection you would need to store "${1}_path" to another variable first which is unnecessary.

You could also use dev|std) eval ... ;; in the case statement at your preference.

于 2013-08-24T06:20:25.747 回答
0

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

MYPATH="/path/to/$1"
$MYPATH/bin/execute
于 2013-08-24T03:41:24.177 回答