【问题标题】:Bash sed delete a line from cronBash sed 从 cron 中删除一行
【发布时间】:2013-06-24 20:34:21
【问题描述】:

有人发现这里的语法有什么问题吗?

CTMPESC=$(sed 's/[\*\.&]/\\&/g' <<<"$CTMP")
crontab -l | sed "/$CTMPESC/d" | crontab -

CTMP 相当于一个简单的 cron 语句,如下所示:

*/8 * * * * cd /home/administrator/anm-1.5.0 && ./anm.sh

我不断收到错误消息:

sed:-e 表达式#1,字符 5:未知命令:`8'

【问题讨论】:

    标签: bash sed


    【解决方案1】:

    如果您想以利用 bash 功能的方式执行此操作,则根本不需要 grep 或 sed 等外部​​工具:

    ctmp_content=$(<"$ctmp")
    crontab -l | while read -r; do
      [[ $REPLY = *"$ctmp_content"* ]] && continue
      printf '%s\n' "$REPLY"
    done | crontab -
    

    【讨论】:

    • 应该[[ $REPLY = *"$ctmp_content"* ]] 不是[[ "$REPLY" == *"$ctmp_content"* ]] 吗?
    • @DaleA,两者都适用于 bash(尤其是 [[ ]]),但我更喜欢 =,因为 = 是 POSIX 测试中唯一合法的字符串比较语法;让人们养成使用它的习惯会阻止他们编写 [ "$foo" == "$bar" ] 并在纯 POSIX 系统无法正确执行其脚本时感到惊讶。
    【解决方案2】:

    这里发生的情况是CTMPESC 中的一个斜杠关闭了模式,而在它之后的任何内容都被解释为命令。你也需要避开斜线。

    / 添加到您转义的字符类别中:

    CTMPESC=$(sed 's/[\*\.&/]/\\&/g' <<<"$CTMP")
    

    【讨论】:

    • ...或者他们可以以不接受正则表达式的方式进行删除,因此根本不需要任何转义,这会更明智。例如,想想grep -F -v
    • @CharlesDuffy 是的。但是这个问题是其中之一,OP 也在 crontabs 上进行替换(使用 sed)。无论如何,这是一个非常中肯的评论。
    • 查尔斯好极了! Lev 让我在上一期中为这个完全相同的脚本专注于 sed,我完全忘记了简单的解决方案。两者都很好,但最终还是使用了 grep 解决方案。谢谢大家!
    猜你喜欢
    • 1970-01-01
    • 2018-05-23
    • 2020-09-26
    • 2018-08-25
    • 2019-12-11
    • 2017-01-10
    • 2019-10-20
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多