【问题标题】:Advice on using crontab with bash将 crontab 与 bash 一起使用的建议
【发布时间】:2013-01-03 00:58:33
【问题描述】:

我想做一个 cron 作业来检查一个文件夹是否存在,如果存在则删除该文件夹的所有内容。例如,我知道在使用 cron 时,以下内容会删除我文件夹的内容:

0 * * * * cd home/docs/reports/;rm -r *

但是,我意识到如果删除了文件夹(或给出了错误的文件路径)而不是删除该文件夹的内容,cd 将失败并且我的操作系统上的所有文件都将被删除。为了防止这种情况(再次)发生,我想先检查文件夹是否存在,然后再删除内容。我想做类似以下的事情,但我不确定如何将 bash 脚本与 cron 一起使用。

if [ -d "home/docs/reports/" ]; then
    cd home/docs/reports/;rm -r *
fi

我是 bash 和 cron 的新手(以防不明显)。

【问题讨论】:

  • 不知道为什么需要cd 到目录来执行命令——只需指定完整路径。

标签: bash cron


【解决方案1】:

我认为cron 使用/bin/sh 来执行命令。 sh 通常是 bash 的子集,并且您没有做任何特定于 bash 的操作。

仅当cd 命令成功时才执行rm 命令:

0 * * * * cd home/docs/reports/ && rm -r *

注意请稍等我测试一下。如果这个笔记不见了,我已经尝试过了,它可以工作。

是的,它有效。 (请注意,测试目录是否存在不太可靠;有可能该目录存在但您不能cd 进入它,或者它可能在测试和cd 命令之间不再存在。)

但实际上你不需要使用这样的复合命令:

 0 * * * * rm -r home/docs/reports/*

仍然是 && 技巧,以及对应的 || 运算符仅在第一个命令失败时执行第二个命令,对于更复杂的操作非常有用。

(您的意思是/home/docs 而不是home/docs?后者将相对于您的主目录进行解释。)

虽然当我尝试它时它工作正常,但使用它需要您自担风险。任何时候将rm -r 与通配符组合在一起,都会存在风险。如果可能,请在您确定不关心的目录中进行测试。如果您想尽可能确定所有内容都已删除,您可以考虑使用rm -rf。最后,请记住,* 通配符与名称以 . 开头的文件或目录不匹配。

#include <stddisclaimer.h>

编辑:

cmets 让我对您想要做的事情有了更好的理解。这些是用户在创建后不久将下载的文件(对吗?),因此您不想删除不到 5 分钟的文件。

假设你有 GNU findutils,你可以这样做:

0 * * * *  find /home/docs/reports/* -cmin +5 -delete 2>/dev/null

find 使用-delete 选项意味着您一次删除一个文件和/或目录,而不是删除整个子树;主要区别在于不会删除包含新文件的旧目录。将-delete 应用于非空目录将失败并显示错误消息。

阅读 GNU 查找文档 (info find) 以获取有关 -cmin-delete 选项的更多信息。请注意,-ctime 操作的是文件最后一次状态更改的时间,不是它的创建时间(Unix 不记录文件创建时间)。对于您的情况,可能是一样的。

(如果省略路径中的/*,则会删除reports目录本身。)

【讨论】:

  • 谢谢@Keith - 是否有一个不太重要的操作,我可以先尝试检查这是否正常?例如,如果我执行 ` 0 * * * * ls /home/docs/reports/*` 会列出所有文件吗?我原来的意思是/home/....
  • @celenius:是的,但是列表将转到标准输出,crond尝试通过电子邮件发送给您。如果失败,您可以使用ls ... &gt; some-file。对于测试 crontab 命令,我经常使用* * * * *(不要忘记在测试后清理你的 crontab)。有用的提示:我将我的 crontab 保存在版本控制系统中。
  • @celenius:需要注意的一件事(正如我在测试后忘记清理自己的 crontab 时发现的那样):如果/home/doc/reports 中没有文件,那么rm -r /home/docs/reports/* 将生成一条错误消息,您将收到一封自动电子邮件。考虑添加2&gt;/dev/null 以丢弃任何错误消息。
  • 感谢您的建议。那么最后一行是:0 * * * * rm -r home/docs/reports/* 2&gt;/dev/null ?
  • @celenius:是的(除了你可能指的是/home/...而不是home/...)。请注意,如果在任意时间在那里创建文件,这有时会在文件创建后立即删除。这是您想要的,还是您想在有机会查看文件后才删除它们?为什么不一开始就避免创建这些文件?
【解决方案2】:

将整个命令(包括 if 逻辑)包装到 script.sh 中。

在脚本顶部指定 #!/bin/bash。

使其可执行:

chmod +x script.sh

然后在您的 cron 作业中指定脚本的完整路径。

【讨论】:

  • 也是一个很好的解决方案。我认为在这种情况下没有必要,但这是一种很好的技术。 (别忘了chmod +x脚本!)
【解决方案3】:

到目前为止,最简单的事情是在 crontab 的顶部执行 SHELL=/bin/bash。对我有用。

【讨论】:

    猜你喜欢
    • 2015-08-26
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    相关资源
    最近更新 更多