字符串扩展 - 将引用变量转义为值

时间:2016-06-30 14:44:09

标签: bash sed cat variable-expansion

要开始使用,请参阅我正在运行的脚本以获取有问题的字符串:

# 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

我的问题是,你能否正确扩展变量,例如print&#34; / home // bash_file&#34;和&#34; /扩展/变量/路径&#34;?我还应该声明虽然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的情况下产生我们想要的结果,并且没有弄乱全局变量(无论如何都太长了),hoorah!

使用eval(虽然可能不安全)可以在this answerhere中找到优秀的亚军:(链接由anubhava的扩展评论提供)。

2 个答案:

答案 0 :(得分:1)

  

我的问题是,您是否可以正确展开变量,例如,打印"/home//bash_file""/expanded/variable/path"

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

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

答案 1 :(得分:1)

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

expanded=$(eval echo $SOURCEFILE)
循环中的

eval运行您提供的扩展命令。由于$SOURCEFILE不是引号,因此它将扩展为例如$HOME/whatever。然后,eval将展开$HOME,然后再将其传递给echoecho将打印结果,expanded=$(...)会将打印结果放入$expanded