为什么有些情况下可以从curl获取到监控信息,有些情况下却无法获取?

为什么有些情况下可以从curl获取到监控信息,有些情况下却无法获取?

当我在交互式 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

相关内容