当我在交互式 bash shell 中运行以下命令时:
$ curl ipinfo.io/ip
123.45.67.890
如果我创建/etc/cron.d/myjob
:
24 * * * * tim ( date && curl ipinfo.io/ip && date ) > /tmp/cron.log 2>&1
在/tmp/cron.log中,我会从curl中获取以下监控信息:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
^M 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0^M100 14 100 14 0 0 147 0 --:--:-- --:--:-- --:--:-- 148
123.45.67.890
为什么有些情况下可以从curl获取到监控信息,有些情况下却无法获取?分别是哪两种情况呢?谢谢。
答案1
不同之处在于,在第一种情况下,您要写入终端;在第一种情况下,您要向终端写入数据。联机curl
帮助页谈到它的进度表时说
默认情况下,curl 会将这些数据显示到终端,因此,如果您调用curl 进行操作并且它即将向终端写入数据,那么它会禁用进度表,否则会弄乱输出混合进度表和响应数据。
当进度表未禁用时,curl
将其输出到标准错误,并将下载的数据输出到标准输入;在您的 cron 作业中,这两个都不是终端,并且它们都被重定向到/tmp/cron.log
,因此您可以在日志文件中看到两者。
此行为意味着curl
在常见使用场景中“表现良好”。如果您用于curl
检索数据并将其输出到终端,如第一个示例所示,您看到的只是数据。如果您用于curl
检索数据并将其输出到文件或管道,您会在终端中看到进度信息。
在您的 cron 作业中,您将两者与双重重定向混合在一起/tmp/cron.log
。如果您不想看到混合的输出,可以使用该-s
选项完全禁用进度表,或将标准错误重定向到另一个文件:
24 * * * * tim ( date && curl -s ipinfo.io/ip && date ) > /tmp/cron.log 2>&1
或者
24 * * * * tim ( date && curl ipinfo.io/ip && date ) > /tmp/cron.log 2>/tmp/cron.err