鉴于我想从包含换行符和特殊字符的文件创建环境变量。线索是该内容可以引用其他必须解释的环境变量。也许我需要比普通 bash 更复杂的工具?
测试文件“testfile.txt”可能如下所示:
* foo
\/-!~
FOO=${FOOBAR}
到目前为止,我自己管理的内容如下:
#!/bin/bash
FOOBAR="SUCCESS"
file="testfile.txt"
var_name="TEST"
name="$file"
content="$(<$file)"
echo "$content"
这给了我一个上下文变量作为输出(因此,正是文件的内容):
* foo
\/-!~
FOO=${FOOBAR}
但是,我怎样才能:
- 让 ${FOOBAR} 设置为上面定义的“SUCCESS”但不碰其余部分?
- 设置一个环境变量TEST,其内容为(1)?
答案1
该答案基于并改编自已接受的答案https://stackoverflow.com/questions/10683349/forcing-bash-to-expand-variables-in-a-string-loaded-from-a-file
#!/bin/bash
export FOOBAR="SUCCESS"
file="testfile.txt"
var_name="TEST"
name="$file"
content="$(envsubst < "$file")"
echo "$content"
eval
与仅替换变量不同envsubst
,不存在通过命令替换或类似方式执行其他程序的风险。这是一个非常简单的 shell 模板工具。
envsubst
是 GNU gettext 国际化实用程序的一部分(在 debian 上,它位于gettext-base
包中)。
请注意,envsubst
(作为外部命令,而不是 shell 内置)只能看到已导出的变量(但请参阅使 shell 将后续定义的变量导出到环境的allexport
标准选项)。sh
答案2
尝试:
eval "content=\$(cat << @@@EOF@@@
$(cat file)
@@@EOF@@@
)"
这将扩展参数、算术和命令替换,并\
用于转义(仅$
和`
本身)和行继续。例如,对于这样的输入:
* foo
\/-!~
FOO=${FOOBAR} $((1+1)) $(uname)
\${FOOBAR}\\foo\
bar
这给出了类似的东西:
* foo
\/-!~
FOO=content-of-$FOOBAR 2 Linux
${FOOBAR}\foobar
如果文件的内容不在您的完全控制之下,那么很明显,这是一个命令注入漏洞。