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

set変数を使用するときは、awkにエスケープシーケンスを解釈するように要求しているので、-vそうしないでください。 awk変数をリテラル文字列に設定ENVIRON[]または使用します。ARGV[]

$ 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スクリプトでシェル変数を使用する方法より多くの情報を知りたいです。

関連情報