避免 awk 注入

Ste*_*art 4 awk pandoc

我有一个脚本,它读取 VCS 日志,将其转换为乳胶,然后使用文本awk替换@COMMITS@模板中的关键字:

untagged=$(get-commit-messages "$server" "$rev")
IFS=$'\n' untagged=( $untagged )  # Tokenize based on newlines
for commit in "${untagged[@]}"; do
  tex+="\\\nui{"                  # Wrap each commit in a custom command
  tex+=$(echo "$commit" | pandoc -t latex --wrap=none)
  tex+="}
"
done

awk -v r="$tex" '{gsub(/@COMMITS@/,r)}1' template
Run Code Online (Sandbox Code Playgroud)

由于提交消息实际上只是文本,因此我pandoc -t latex用来确保所有内容都为 Latex 解析器正确转义。

我的问题是awk解析器未转义这些。如果我_在提交消息中找到 a ,pandoc会将其替换为\_,但随后awk会将其转换回并发出警告:

awk: warning: escape sequence `\_' treated as plain `_'
Run Code Online (Sandbox Code Playgroud)

这将导致乳胶解析器失败。

有没有办法让我防止awk不转义的东西?如果不是,我将寻找awk文本替换的非解决方案。

Ed *_*ton 8

您要求 awk 在通过 using 设置变量时解释转义序列,-v所以不要这样做 - 使用ENVIRON[]ARGV[]改为将 awk 变量设置为文字字符串:

$ shellvar='foo\tbar'

$ awk -v awkvar="$shellvar" 'BEGIN{print awkvar}'
foo     bar

$ shellvar="$shellvar" awk 'BEGIN{awkvar=ENVIRON["shellvar"]; print awkvar}'
foo\tbar

$ awk 'BEGIN{awkvar=ARGV[1]; delete ARGV[1]; print awkvar}' "$shellvar"
foo\tbar
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅how-do-i-use-shell-variables-in-an-awk-script