【问题标题】:bash script runs from shell but not from cron jobbash 脚本从 shell 运行,但不是从 cron 作业运行
【发布时间】:2023-07-24 06:02:01
【问题描述】:

cron 安装是 vixie-cron

/etc/cron.daily/rmspam.cron

#!/bin/bash
/usr/bin/rm /home/user/Maildir/.SPAM/cur/*;

我有这个简单的 bash 脚本,我想将它添加到 cron 作业中(之前还包括垃圾邮件学习命令),但这部分总是失败,并显示“找不到文件或目录”据我所知,metachar 不是作为 cron 作业运行时可以正确进行干预。如果我从命令行执行脚本,它工作正常。

我想知道为什么这不起作用,当然还有一个可行的解决方案:)

谢谢

编辑 #1 当我得到流行的问题徽章时,又回到了这个问题。我第一次这样做,

#!/bin/bash
find  /home/user/Maildir/.SPAM/cur/ -t file | xargs rm

最近正在阅读 xargs 手册页并将其更改为这个

#!/bin/bash
find  /home/user/Maildir/.SPAM/cur/ -t file | xargs --no-run-if-empty rm

短 xargs 选项是 -r

【问题讨论】:

  • 请编辑并添加您的 crontab 中的行。
  • 他在下面的评论中提到它在 /etc/cron.daily 中

标签: linux bash cron


【解决方案1】:

如果目录中没有文件,则通配符不会被展开,直接传递给命令。没有名为“*”的文件,然后命令失败并显示“找不到文件或目录”。试试这个:

if [ -f /home/user/Maildir/.SPAM/cur/* ]; then
    rm /home/user/Maildir/.SPAM/cur/*
fi

或者只是对 rm 使用“-f”标志。此命令的另一个问题是当命令行的最大长度有太多垃圾邮件时会发生什么。总体而言,这样的事情可能会更好:

find /home/user/Maildir/.SPAM/cur -type f -exec rm '{}' +

如果您有一个旧的 find 一次只执行 rm 一个文件:

find /home/user/Maildir/.SPAM/cur -type f | xargs rm

它处理的文件太多,也没有文件。感谢 Charles Duffy 指出 find 中 -exec 的 + 选项。

【讨论】:

  • 实际上,你不需要 xargs 和一个足够新的 find:find /home/user/Maildir/.SPAM/cur -type f -exec rm -f '{}' '+'
  • find 不应该以 \; 结尾吗? ?
  • 删除文件是如此频繁的任务,find 也支持-delete 操作。没有明确需要做-exec rm '{}'
  • 这取决于你的发现。 BSD 和 Linux 有 -delete,但老式的 Unix 可能没有。请注意,“老式”不仅意味着“旧”,还意味着“Solaris”。我的“find(1) 肌肉记忆”来自 80 年代,在我的答案的第一个版本中,甚至 '+' 都不能与 exec 一起使用;我一直在使用“查找任何 -print0 | xargs -0 命令”很长时间。显然在某些时候我适应了文件名中的空格......
  • -delete 在 Ubuntu 16.04 中不可用。一定是老了。
【解决方案2】:

您是否在 cronjob 中指定脚本的完整路径?

00 3 * * * /home/me/myscript.sh

而不是

00 3 * * * myscript.sh

另一方面,在我可以访问的所有 linux 机器上,它都是 /bin/rm。您是否仔细检查过它确实在您的机器上是 /usr/bin/rm 吗?

【讨论】:

  • 脚本位于 /etc/cron.daily/ 中 /etc/crontab 中
  • 这是在 gentoo 发行版上设置 vixie-cron 的默认方式。是的,它是 /bin/rm,尽管有一个指向 /usr/bin/rm 的链接。也许下次我会使用 which rm 来查找路径而不是猜测
【解决方案3】:

尝试添加

MAILTO=your@email.address

到您的 cron 文件的顶部,您应该会收到任何输入/错误邮件。

还可以考虑将命令添加为 cronjob

0 30 * * * /usr/bin/rm /home/user/Maildir/.SPAM/cur/*

【讨论】:

    【解决方案4】:

    尝试使用强制选项,忘记添加 rm 命令的路径。我认为应该不需要...

    rm -f
    

    这样可以保证即使目录中没有文件,rm命令也不会失败。如果这是 shell 脚本的一部分,那么 * 应该可以工作。在我看来,您可能有一个空目录...

    我知道脚本的其余部分正在执行,对吧?

    【讨论】:

      【解决方案5】:

      rm 真的位于您系统上的/usr/bin/ 中吗?我一直认为rm应该驻留在/bin/中。

      【讨论】:

        最近更新 更多