为从标准输入接收到的每一行添加时间戳

Def*_*iti 1 bash stdin timestamp

您好,我正在尝试使用 bash 创建日志,但我得到的时间是错误的。我在后台运行这个。

# log code here before executing curl script log "Yay I was started"

curl https://example.com/process | sed "s/^/$(date -u) /" >> /path/to/logs.log &
Run Code Online (Sandbox Code Playgroud)

处理curl后设置的时间是执行它的时间,而不是我得到响应后的时间。我需要得到回复后的时间。

这是示例输出(错误响应)

Fri Aug 21 01:43:12 UTC 2020 Yay I was started
Fri Aug 21 01:43:12 UTC 2020 Yay I was the response returned by the url
Run Code Online (Sandbox Code Playgroud)

这里的 urlhttps://example.com/process会休眠 2 秒,但正如您所看到的,时间与执行时和执行后我们收到响应的时间相同。

正确反应

Fri Aug 21 01:43:12 UTC 2020 Yay I was started
Fri Aug 21 01:43:14 UTC 2020 Yay I was the response returned by the url
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

Léa*_*ris 5

您的问题是因为sed "s/^/$(date -u) /"在启动时捕获日期字符串并将其放置在每行的开头。不会为 的响应中每个传入的新行更新日期字符串curl

使用 , 将日期添加到每行前面awk比使用 , 更安全,因为它将捕获每行的新日期。sed

您的原始日期格式是区域设置格式,当地时间。如果您愿意的话,它已按原样保存在这里;但通常日志时间戳最好使用 iso.org : I​​SO 8601 格式或 UTC 相对 Unix 时间戳打印。

curl https://example.com/process |
  awk '{ printf("%s %s\n", strftime("%c", systime()), $0) }' >>/path/to/logs.log &
Run Code Online (Sandbox Code Playgroud)

使用 ISO-8601 时间戳:

curl https://example.com/process |
  awk '{ printf("%s %s\n", strftime("%Y-%m-%dT%H:%M:%S%z", systime()), $0) }' \
    >>/path/to/logs.log &
Run Code Online (Sandbox Code Playgroud)

请参阅man strftime时间格式。