使用 sed 编辑 crontab
Use sed to edit 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 命令最终会进入脚本。
无论是使用 sed 还是其他工具都不会有太大区别。
我也会使用 sed。
但要正确修改 cron 正在使用的内容,请介意使用 crontab
命令。
不要尝试只编辑数据文件(例如 /etc/crontab
在某些系统上)。 Cron 不会接收更改!!!
您可能会使用管道:
crontab -l | sed -e "s#\# 5 \* \* \* 3 bash test.sh#5 * * * 3 bash test.sh#"| crontab
执行更改。
然而,将 enabling/disabling 的功能添加到 运行 的脚本中不是更简单吗?
Sed 非常适合匹配特定的正则表达式和以特定方式操作文本,但在我看来这不是其中之一。虽然您可以使用 sed 来完成这项任务,但结果可能过于复杂和脆弱。
您的初始尝试是:
sed "s#\# 5 * * * 3 bash test.sh#5 * * * 3 bash test.sh#"
这会失败,因为 *
字符是正则表达式中的一个特殊字符,并被翻译为 "zero or more of the previous atom"(在本例中为 space)。严格来说,您可以通过转义正则表达式中的星号(在您的替换模式中不需要)来让这个 sed 脚本工作。
但这只对这种特定模式有帮助。如果您的一位同事决定 运行 在整点后 6 分钟而不是 5 分钟执行此脚本,以避免与其他脚本发生冲突怎么办?或者在注释符后面有一个space?突然你的 sed 替换失败了。
要取消注释掉 每个 个有问题的脚本,您可以使用:
crontab -l | sed '/# *\([^ ][^ ]* *\)\{5\}[^ ]*test\.sh/s/^# *//' | crontab -
如果您使用的是 more modern sed,您可以将此 BRE 替换为稍短的 ERE:
crontab -l | sed -E '/# *([^ ]+ *){5}[^ ]*test\.sh/s/^# *//' | crontab -
这会获取 crontab -l
的输出,这显然是您完整的 crontab,使用 sed 对其进行操作,然后使用 crontab -
根据其输出编写一个新的 crontab。 sed 脚本匹配搜索与看起来像有效的 crontab 匹配的行(以避免只提及您的脚本的实际注释),然后进行简单的替换以仅删除开头的注释字符。匹配的模式如下所示:
# *
- 匹配后跟零个或多个 spaces 的注释字符
([^ ]+ +){5}
- 五个非 space 字符串,后跟 spaces
[^ ]*
- 任意数量的非 space 字符,最多为:
test\.sh
- 你的脚本。
但是请注意,这不匹配 所有 个有效的 crontab 时间,其中可能包括 @reboot
、@weekly
、[=23 等标签=],等等。查看 man 5 crontab
了解详情。
像 awk
这样的非 sed 替代方案可能是合适的。以下 awk 解决方案对我来说更有意义:
crontab -l | awk -v script="test.sh" '
{ field=6 }
/^# / { field++ }
index($field,script) { sub(/^#/,"") }
1' \
| 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 命令最终会进入脚本。
无论是使用 sed 还是其他工具都不会有太大区别。 我也会使用 sed。
但要正确修改 cron 正在使用的内容,请介意使用 crontab
命令。
不要尝试只编辑数据文件(例如 /etc/crontab
在某些系统上)。 Cron 不会接收更改!!!
您可能会使用管道:
crontab -l | sed -e "s#\# 5 \* \* \* 3 bash test.sh#5 * * * 3 bash test.sh#"| crontab
执行更改。
然而,将 enabling/disabling 的功能添加到 运行 的脚本中不是更简单吗?
Sed 非常适合匹配特定的正则表达式和以特定方式操作文本,但在我看来这不是其中之一。虽然您可以使用 sed 来完成这项任务,但结果可能过于复杂和脆弱。
您的初始尝试是:
sed "s#\# 5 * * * 3 bash test.sh#5 * * * 3 bash test.sh#"
这会失败,因为 *
字符是正则表达式中的一个特殊字符,并被翻译为 "zero or more of the previous atom"(在本例中为 space)。严格来说,您可以通过转义正则表达式中的星号(在您的替换模式中不需要)来让这个 sed 脚本工作。
但这只对这种特定模式有帮助。如果您的一位同事决定 运行 在整点后 6 分钟而不是 5 分钟执行此脚本,以避免与其他脚本发生冲突怎么办?或者在注释符后面有一个space?突然你的 sed 替换失败了。
要取消注释掉 每个 个有问题的脚本,您可以使用:
crontab -l | sed '/# *\([^ ][^ ]* *\)\{5\}[^ ]*test\.sh/s/^# *//' | crontab -
如果您使用的是 more modern sed,您可以将此 BRE 替换为稍短的 ERE:
crontab -l | sed -E '/# *([^ ]+ *){5}[^ ]*test\.sh/s/^# *//' | crontab -
这会获取 crontab -l
的输出,这显然是您完整的 crontab,使用 sed 对其进行操作,然后使用 crontab -
根据其输出编写一个新的 crontab。 sed 脚本匹配搜索与看起来像有效的 crontab 匹配的行(以避免只提及您的脚本的实际注释),然后进行简单的替换以仅删除开头的注释字符。匹配的模式如下所示:
# *
- 匹配后跟零个或多个 spaces 的注释字符
([^ ]+ +){5}
- 五个非 space 字符串,后跟 spaces[^ ]*
- 任意数量的非 space 字符,最多为:test\.sh
- 你的脚本。
但是请注意,这不匹配 所有 个有效的 crontab 时间,其中可能包括 @reboot
、@weekly
、[=23 等标签=],等等。查看 man 5 crontab
了解详情。
像 awk
这样的非 sed 替代方案可能是合适的。以下 awk 解决方案对我来说更有意义:
crontab -l | awk -v script="test.sh" '
{ field=6 }
/^# / { field++ }
index($field,script) { sub(/^#/,"") }
1' \
| crontab -
虽然有点长,但我觉得它更容易阅读和理解。