使用sed编辑crontab

时间:2016-03-31 10:14:37

标签: bash shell unix sed crontab

我正在编写一个sed命令,该命令应取消注释crontab中的条目。有一个更好的方法吗?想到的第一个选择是sed。

示例:

crontab -l

# 5 * * * 3 bash test.sh

sed命令应取消注释此条目。这就是我现在所拥有的。

sed "s#\# 5 * * * 3 bash test.sh#5 * * * 3 bash test.sh#"

显然这个sed命令不能完成任务。

ps:sed命令最终会进入脚本。

2 个答案:

答案 0 :(得分:2)

Sed很适合匹配特定的正则表达式和以某种方式处理文本,但在我看来,这似乎不是其中之一。虽然你可以使用sed来完成这项任务,但结果可能过于复杂和脆弱。

您最初的尝试是:

sed "s#\# 5 * * * 3 bash test.sh#5 * * * 3 bash test.sh#"

此操作失败,因为*字符是正则表达式中的特殊字符,并被翻译为"前一个原子的零个或多个" (在这种情况下,一个空格)。严格来说,您可以通过转义正则表达式中的星号(在替换模式中不需要)来使用此sed脚本。

但这只对这种特定模式有所帮助。如果您的一位同事决定在一小时后而不是5小时运行此脚本,以避免与另一个脚本发生冲突,该怎么办?或者评论字符后面还有一个空格?突然间你的sed替换失败了。

要取消注释所讨论的每个注释事件,您可以使用:

crontab -l | sed '/# *\([^ ][^ ]*  *\)\{5\}[^ ]*test\.sh/s/^# *//' | crontab -

如果您使用的是more modern sed,则可以使用略短的ERE替换此BRE:

crontab -l | sed -E '/# *([^ ]+  *){5}[^ ]*test\.sh/s/^# *//' | crontab -

这将获取crontab -l的输出,这显然是您的完整crontab,使用sed操作它,然后使用crontab -根据其输出写入新的crontab。 sed脚本匹配搜索匹配看起来像有效crontab的行(为了避免简单提及您的脚本的实际注释),然后执行简单替换以仅删除开头的注释字符。匹配的模式如下所示:

  • # * - 匹配注释字符后跟零个或多个空格
  • ([^ ]+ +){5} - 五个非空格字符串,后跟空格
  • [^ ]* - 任意数量的非空格字符,最多可达:
  • test\.sh - 你的剧本。

但请注意,这与所有有效的crontab时间不匹配,其中可能包含@reboot@weekly@midnight等标记,请查看man 5 crontab了解详情。

awk这样的非sed替代品可能是有序的。以下awk解决方案对我来说更有意义:

crontab -l | awk -v script="test.sh" '
  { field=6 }
  /^# / { field++ }
  index($field,script) { sub(/^#/,"") }
  1' \
| crontab -

虽然时间稍长,但我发现阅读和理解更容易。

答案 1 :(得分:1)

使用sed还是其他工具不会产生太大影响。 我也用sed。

但要正确修改cron正在使用的内容,请注意使用crontab命令 不要只尝试编辑数据文件(例如某些系统上的/etc/crontab)。 Cron不会接受改变!!!。

您可以使用管道:

crontab -l | sed -e "s#\# 5 \* \* \* 3 bash test.sh#5 * * * 3 bash test.sh#"| crontab 

执行更改。

然而,在正在运行的脚本中添加启用/禁用功能不仅简单吗?