我安排了这个 cron:
0 * * * * ping -D -O -c 3492 8.8.8.8 | grep received > /home/user/.direc/packet_drops.txt
该命令在手动运行时工作正常,并在 ping 完成后正常导出到 .txt 文件。
当在 cron 中运行时,该文件保持为空。我已经在同一用户下尝试过手动命令和 cron,同样的问题。
我缺少什么?我也尝试过重定向错误输出,但它仍然为空。
答案1
正如对您的问题的评论中所指出的,当您查看文件时文件为空的可能原因/home/user/.direc/packet_drops.txt
是它已被 cron 作业的下一次执行截断。
作业一开始就会设置管道,并作为初始设置的一部分执行重定向。ping
每隔一小时启动一次,运行 3492 秒,因此packet_drops.txt
在被截断之前,您每小时只有 108 秒的阅读窗口(理论上)。
一种仅在长时间运行的作业终止时才覆盖日志文件的方法(正如您在评论)是将其输出打印到临时文件并在作业结束时替换目标文件。
将其管理为更容易script
:
#!/bin/sh
trap 'rm -f -- "$tmpfile"' EXIT
tmpfile=$(mktemp)
ping -D -O -c 3492 8.8.8.8 | grep received >"$tmpfile"
cat -- "$tmpfile" >/home/user/.direc/packet_drops.txt
并定义一个更简单的 cron 作业(它失败的方式更少,因此更容易调试):
0 * * * * /path/to/script
或者,为了保持一句简洁,您可以利用awk
操作文件的能力:
ping -D -O -c 3492 8.8.8.8 | awk -v file=/h..s.txt '/received/ { print >file }'
(缩短文件名只是为了该代码块的可读性)。
此 AWK 脚本仍会截断输出文件,但仅当received
在输入数据中找到行匹配时才执行此操作。
答案2
Crontab 有一组最小的环境变量。 cronjob 可能找不到 ping 或 grep 命令。您可以使用简单的命令在 cronjob 中检查环境变量:
* * * * * env &> /tmp/cron-env.txt
等待该作业运行一次,然后再次将其删除。在输出中搜索 PATH 变量并检查是否包含 ping 和 grep 命令的路径。
您可以使用以下命令找到这些命令的路径:
whereis <command>
如果不包含它们,您可以将 PATH 变量添加到您的 cronjob 中:
PATH=/bin:/usr/sbin:/usr/bin:/sbin:
* * * * * some-cron-job