字符串扩展 - 将带引号的变量转义为值

String expansion - escaped quoted variable to value

首先,这是我正在 运行 获取有问题的字符串的脚本:

# sed finds all sourced file paths from inputted file.
#
# while reads each match output from sed to $SOURCEFILE variable.
# Each should be a file path, or a variable that represents a file path.
# Any variables found should be expanded to the full path.
#
# echo and calls are used for demonstractive purposes only 
# I intend to do something else with the path once it's expanded.

PATH_SOME_SCRIPT="/path/to/bash/script"

while read -r SOURCEFILE; do
    echo "$SOURCEFILE"
    "$SOURCEFILE"
    $SOURCEFILE
done < <(cat $PATH_SOME_SCRIPT | sed -n -e "s/^\(source\|\.\|$include\) //p")

您可能还希望使用以下内容将其作为模拟数据进行测试:

[ /path/to/bash/script ]

#!/bin/bash
source "$HOME/bash_file"
source "$GLOBAL_VAR_SCRIPT_PATH"

echo "No cow powers here"

对于 tl;dr 船员,基本上 while 循环在模拟数据上吐出以下内容:

"$HOME/bash_file"
bash: "$HOME/bash_file": no such file or directory
bash: "$HOME/bash_file": no such file or directory
"$GLOBAL_VAR_SCRIPT_PATH"
"$GLOBAL_VAR_SCRIPT_PATH": command not found
"$GLOBAL_VAR_SCRIPT_PATH": command not found

我的问题是,你能否让变量正确扩展,例如打印“/home//bash_file”和“/expanded/variable/path”?我还应该声明 虽然 eval 有效但我不打算使用它,因为它 potential insecurities.

提示 cat | sed 中使用的任何变量值都将全局可用,包括调用脚本,所以这不是因为脚本无法调用变量值。


第一个解决方案尝试

使用 anubhava 的 envsubst 解决方案:

SOMEVARIABLE="/home/nick/.some_path"
while read -r SOURCEFILE; do 
    echo "$SOURCEFILE"
    envsubst <<< "$SOURCEFILE"; 
done < <(echo -e "\"$SOMEVARIABLE\"\n\"$HOME/.another_file\"")

这将输出以下内容:

"$SOMEVARIABLE"
""
"/home/nick/.another_file"
"/home/nick/.another_file"

不幸的是,它没有扩展变量!哦亲爱的:(


第二次尝试解决方案

基于第一次尝试:

export SOMEVARIABLE="/home/nick/.some_path"
while read -r SOURCEFILE; do 
    echo "$SOURCEFILE"
    envsubst <<< "$SOURCEFILE"; 
done < <(echo -e "\"$SOMEVARIABLE\"\n\"$HOME/.another_file\"")
unset SOMEVARIABLE

无需 eval 且无需扰乱全局变量(反正太长了)就可以产生我们想要的结果,太棒了!


进一步建议使用 eval(尽管可能不安全)可以在 and here 中找到优秀的亚军(link 由 anubhava 的扩展评论提供)。

My question is, can you get the variable to expand correctly, e.g., print "/home//bash_file" and "/expanded/variable/path"?

是的,您可以使用 envsubst program,替代环境变量的值:

while read -r sourceFile; do
   envsubst <<< "$sourceFile"
done < <(sed -n "s/^\(source\|\.\|$include\) //p" "$PATH_SOME_SCRIPT")

我想你是在问如何递归扩展 bash 中的变量。尝试

expanded=$(eval echo $SOURCEFILE)

在你的循环中。 eval 运行您给它的扩展命令。由于 $SOURCEFILE 不在引号中,它将被扩展为 $HOME/whatever。然后 eval 将扩展 $HOME,然后再将其传递给 echoecho会打印结果,expanded=$(...)会把打印结果放在$expanded.