避免 awk 注入

避免 awk 注入

我有一个脚本,它读取 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

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

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

awk: warning: escape sequence `\_' treated as plain `_'

这将导致 Latex 解析器失败。

我有办法防止awk无法转义的事情吗?如果没有,我将寻找一种非awk文本替换的解决方案。

答案1

您要求 awk 在使用设置变量时解释转义序列,-v所以不要这样做 - 使用ENVIRON[]orARGV[]来将 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

如何在 awk 脚本中使用 shell 变量了解更多信息。

相关内容