Bash 脚本不会解释变量内的变量

Bash 脚本不会解释变量内的变量

我需要提取配置文件中设置的路径,以便在 bash 脚本中使用它。该路径在所述文件内如下所示:

DIR = "${HOME}/test/tmp"

我需要在不带引号的情况下提取它,这就是我的做法:

TESTVAR="$(cat /home/user/path/to/file.conf | grep ^DIR | grep -o '".*"' | tr -d '"')"

问题是命令不能“正确”解释 ${HOME} 变量。假设我调用echo $TESTVAR- 结果,而不是这样:

/home/user/test/tmp

我明白了:

${HOME}/test/tmp

所以我不能将它用作脚本内命令的参数!

请问漂亮吗?

答案1

扩展不会被递归应用。这样做将无法处理嵌入美元符号的任意数据。 (一个相关的问题是,引号和重定向以及其他运算符也只是扩展后的常规字符。)

一个比较常见的习惯是使用像这样的配置文件作为实际的 shell 脚本,所以(就像 Debian 中的/etc/default),所以该文件将是

DIR="${HOME}/test/tmp"

你会读它

. configfile

当然,这有一个问题,即该文件是完整的 shell 脚本,必须符合 shell 语法,并且配置可以运行任意命令。

另一种可能性是通过 运行文件envsubst,例如使用问题中的文件,envsubst < configfile将输出:

DIR = "/home/me/test/tmp"

或者你可以用来envsubst '$HOME $OTHER $VARS'扩展一些特定的。

请注意,与 shell 脚本不同的是,envsubst它不会从输入文件中读取任何分配。例如,ROOTPATH第二行使用的值是envsubst从环境中获取的值,它与第一行的“赋值”无关:

ROOTPATH=/something/$USER
LOGPATH=$ROOTPATH/logs

答案2

这是获得您所追求的东西的不必要的复杂方式!您所需要的只是(我还更改为小写变量名称,请避免对 shell 脚本变量使用大写字母,因为它们用于环境变量,这可能会导致名称冲突):

testvar="$(grep -oP '^DIR\s*=\s*"\K[^"]+' /home/user/path/to/file.conf)"

这会让你得到testvar=${HOME}/test/tmp。要扩展$HOME,您现在需要评估它:

testvar=$(eval echo "$testvar")

然而,用于eval任意代码是非常危险的。如果您正在读取的文件包含命令,则将运行该命令。所以给出的方法@ilkkachu 的回答更好更安全。

相关内容