在不丢失特殊字符的情况下重定向脚本中的 shell 命令

Redirect shell command in a script without loosing special characters

从用作包装器的另一个脚本,我正在尝试配置将由 webhook 触发的 AWS SNS 警报。问题是我正在丢失 SED 命令中的所有特殊字符,这将帮助我从一些自定义命令(如 'alerts':

中消除 ASCI 颜色字符
printf 'aws sns publish --subject "$(hostname -f)" --message "$(alerts -v|sed 's/\x1b\[[0-9;]*m//g' && echo -e "\n\n" && alerts --components|sed 's/\x1b\[[0-9;]*m//g')"' > /opt/webhook/sns.sh

基本上我试图在 /opt/webhook/sns.sh 中重定向这个命令来执行。

printf 本身是在解释 \x1b,而不是按字面意思书写。我会将两个命令替换移到格式字符串之外,既是为了可读性,也是为了保护 \x1b 不被 printf.

解释
printf 'aws sns publish --subject "%s" --message "%s"\n' \
  '$(hostname -f)' \
  "$(alerts -v | sed 's/\x1b\[[0-9;]*m//g' &&
     printf '\n\n' &&
     alerts --components | sed 's/\x1b\[[0-9;]*m//g')" \
  > /opt/webhook/sns.sh

您会注意到引用很棘手;单引号不能出现在单引号字符串内,所以我使用双引号并明确转义开始命令替换的 $

我实际上根本不会使用 printf,但是 cat 和这里的文档:

cat <<'EOF' > /opt/webhook/sns.sh
aws sns publish --subject "$(hostname -f)" --message "$(alerts -v|sed 's/\x1b\[[0-9;]*m//g' && echo -e "\n\n" && alerts --components|sed 's/\x1b\[[0-9;]*m//g')"
EOF

理想情况下,alerts 要么提供一种禁用彩色输出的方法,要么足够智能,在其标准输出不是终端时自动禁用彩色输出,因此您可以省去 sed 完全命令。