在 Bash 中转义双引号和单引号

Escape double and single quotes in Bash

我每个月的每个第一个星期日每季度都有一个 Cron 作业 运行:

0 0 1-7 3,6,9,12 * [ "$(date '+\%a')" == "Sun" ] && /script.sh

现在我想像这样使用 echo 自动安装它:

(crontab -l ; echo "0 0 1-7 3,6,9,12 * [ "$(date '+\%a')" == "Sun" ] && /script.sh") | crontab -

虽然转义 \"Sun"\ 工作正常但我无法转义 "$(date '+\%a')" 因为这是双引号 echo 命令中单引号和双引号与 \ 的混合。

你不需要使用疯狂的转义。使用 bash 提供的 [[ ... ]] 而不是旧的(并且容易出错) [ ... ]:

所以使用:

0 0 1-7 3,6,9,12 * [[ $(date +\%a) == Sun ]] && /script.sh

要自动安装它,请使用:

(crontab -l ; echo '0 0 1-7 3,6,9,12 * [[ $(date +\%a) == Sun ]] && /script.sh') | crontab -

PS:确保在 crontab 文件中在此行之前设置 SHELL=/bin/bash

您可以使用 here document 来避免引用 crontab 条目:

read -r crontab_entry <<'END_CRONTAB_ENTRY'
0 0 1-7 3,6,9,12 * [ "$(date '+\%a')" == "Sun" ] && /script.sh
END_CRONTAB_ENTRY

(crontab -l; printf '%s\n' "$crontab_entry") | crontab -
  • 请参阅对 Why is printf better than echo? 的公认且优秀的回答,以了解我为何使用 printf 而不是 echo 来输出 crontab 条目的解释。
  • 请注意,date '+\%a' 产生类似于 \Sun 的输出(对于某些版本的 date 程序)。你可能想要 date '+%a'.
    更新: 说明 date '+\%a' 中的反斜杠是必要的,因为命令在 crontab 中。)
  • 另请注意,%a 日期格式生成的字符串取决于语言环境。星期天可能不是 Sun。使用数字日更安全(例如 [ "$(date '+%w')" -eq 0 ])。
  • 最后,请注意将 ==[...] 一起使用在 shell 之间不可移植。使用 = 除非您 确定 crontab 条目只会 运行 和 Bash.