一些同事建议我添加一个 cron 作业来做一些事情,但执行crontab -e
并添加以下行:
0 1 * * * . /path/to/some/file.bash
Run Code Online (Sandbox Code Playgroud)
为了确保这件事正常工作,我将其更改为
0 1 * * * . /path/to/some/file.bash && date >> /some/log
Run Code Online (Sandbox Code Playgroud)
这样我就可以检查/some/log
每天确实没有更多线路。
但这并没有发生。
为了调试的目的,我刚刚将这三行添加到crontab -e
,
* * * * * echo "uffa" >> /home/me/without-user
* * * * * me echo "uffa" >> /home/me/with-user
* * * * * . echo "uffa" >> /home/me/with-any-user
Run Code Online (Sandbox Code Playgroud)
我的用户名在哪里me
,这导致所有三个文件都被创建,但只有第一个文件每分钟增长一行,正如您在 8 分钟后所做的检查中看到的那样:
0 1 * * * . /path/to/some/file.bash
Run Code Online (Sandbox Code Playgroud)
发生了什么?第二行和第三行是否使用了错误的语法,因为该行上多了一个条目?如果是这样,那么为什么还要创建该文件?
我刚刚验证了运行像这样的无意义命令jflkdasjflaksd > someFile
确实会创建一个空someFile
,这告诉我这两行
* * * * * me echo "uffa" >> /home/me/with-user
* * * * * . echo "uffa" >> /home/me/with-any-user
Run Code Online (Sandbox Code Playgroud)
只是错误的,并且由于 shell 命令行处理的工作方式,文件甚至在错误发生之前就已创建。
然而,这些都是对其他人有用的线路。怎么了?
好的,首先,有两种略有不同的crontab
格式。一个用于每用户 crontab,另一个用于系统 crontab(/etc/crontab
以及 中的文件/etc/cron.d/
)。
个人 crontab 有五个字段用于时间和日期,其余部分用于命令。系统 crontab 有五个字段用于时间和日期,第六个字段用于用户运行命令,其余行用于命令。如果您愿意的话,总计 6 和 7,尽管命令的最后一个“字段”的定义与其他字段有点不同。
个人 crontab 没有用户名字段,因为 crontab 隐含了所有者是谁,并且普通用户无论如何都不允许以其他人的身份运行程序。
(正如评论中所指出的,root
用户的个人 crontab 也只是像任何其他用户一样的个人 crontab。它没有用户名字段,尽管root
在其他方面有点特殊。所以不仅是/etc/crontab
一个与你以 root 身份获得的一个crontab -e
,它也有不同的格式。)
然后是.
. 它告诉 shell 读取作为参数命名的脚本,并在当前 shell 中运行它(某些 shell 称为source
的别名.
)。此后任何函数定义和变量分配都将可见,这与将脚本作为单独的程序运行时不同。
线路
0 1 * * * . /path/to/some/file.bash
Run Code Online (Sandbox Code Playgroud)
告诉 shell(cron 启动的).../file.bash
在同一个 shell 中运行。我不确定为什么他们建议这样做,而不是直接运行不带点的命令。不必初始化新的 shell 可能会有轻微的优化,但缺点是脚本必须在 cron 启动的 shell 中运行。如果 cron 启动一个普通的 sh,那么这是行不通的,但脚本是针对 zsh 的,或者是针对 Python 的。
如果该行位于全局 crontab 中,则意味着/path/to/some/file.bash
以 user 身份运行.
。这可能不是它的意思。
为了简单起见,我建议这样做(在使脚本可执行并添加适当的 hashbang 行(如果尚未完成)之后):
0 1 * * * /path/to/some/file.bash
Run Code Online (Sandbox Code Playgroud)
然后,如果不起作用. /some/script && date >> logfile
,首先要查看脚本是否因错误退出。您&&
在那里使用了运算符,它告诉 shell 仅在左侧命令成功退出时才运行右侧命令。你可以. /some/script; date >> logfile
无条件地运行它。或者,您. /some/script; printf "run at %s, exit status %d\n" "$(date)" "$?" >> logfile
也可以尝试保存退出状态。
至于这些:
* * * * * echo "uffa" >> /home/me/without-user
* * * * * me echo "uffa" >> /home/me/with-user
* * * * * . echo "uffa" >> /home/me/with-any-user
Run Code Online (Sandbox Code Playgroud)
在个人 crontab 中,第一个告诉 shell 运行echo
,第二个告诉 shell 运行名为 的命令me
,第三个告诉 shell 运行名为 的脚本echo
。所有这些都包含重定向,并且重定向是在命令启动之前由 shell 处理的,因此在所有情况下都会创建您的文件。(它们必须如此,因为 shell 在尝试之前无法知道该命令是否可运行,如果成功,控制权将传递给该命令,因此 shell 无法再对重定向执行任何操作。)
后面两个可能会给出错误消息,如果您的 cron 设置正确,您应该会在电子邮件中收到这些消息。
然而,这些都是对其他人有用的线路。怎么了?
如上所述,. /path/to/some/script
尝试在 shell 中运行给定的脚本,对于二进制命令来说它将失败,因此. echo ...
不太可能工作。0 1 * * * username echo ...
可以在全局 crontab 中工作,但可能不能在个人 crontab 中工作。0 1 * * * . whatever
不太可能在全球范围内工作,因为.
可能不是有效的用户名。
归档时间: |
|
查看次数: |
178 次 |
最近记录: |