您可以获取“此处文档”吗?

您可以获取“此处文档”吗?

假设我有一个 bash 脚本,它充当另一个 bash 脚本的配置文件:

配置.sh:

verbose=yes
echo "Malicious code!"
name=test

脚本.sh:

source config.sh
echo "After sourcing: verbose='$verbose', name='$name'"

问题是,这不是很安全,因为 config.sh 中放入的任何内容都会运行:

$ ./script.sh
Malicious code!
After sourcing: verbose='yes', name='test'

为了使其更安全,我想我应该 grep 出赋值操作并只执行这些操作。我将通过传递source“此处文档”来完成:

脚本.sh:

source <<EOF
$(grep -P '^\s*\w+=' test.sh)
EOF
echo "After sourcing: verbose='$verbose', name='$name'"

(是的,我知道正则表达式不是那么强大;它只是一个占位符。)可悲的是,源代码似乎与这里的文档配合得不好:

./script.sh: line 1: source: filename argument required
source: usage: source filename [arguments]
After sourcing: verbose='', name=''

显然,我可以做很多事情来从文件中获取配置数据,而且无论如何这可能更安全。

但我仍然心有余悸;我想弄清楚我所尝试的是否有效。有什么建议么?

答案1

source <(cat << EOF
A=42
EOF
)
echo $A

输出:

42

答案2

source需要一个文件名,您无法将输入重定向到它。

在我的系统上,我可以使用进程替换:

source <( grep = test.sh )

替换=为适当的正则表达式。

答案3

您可以直接eval使用:

eval "$(grep -P '^\s*\w+=' config.sh)" 
#quotes needed if you want the full content of the file (including newlines etc.)

采购本质上与以下相同:

eval "$(cat file)"   

但请注意,人们可能会在等号右侧执行所有 kinz 的 codez:

a=$(evil_code_here)
b=`evil_code_here`
c="something" evil_code_here
#etc.

你需要一个更好的过滤器。

相关内容