简体   繁体   English

如何在将标准输出重定向到 Bash 中的文件时添加时间戳?

[英]How to add timestamp while redirecting stdout to file in Bash?

I have a program (server) and I am looking for a way (script) that will redirect (or better duplicate) all its stdout to file and add timestamp for each entry.我有一个程序(服务器),我正在寻找一种方法(脚本),将其所有stdout重定向(或更好地复制)到文件并为每个条目添加时间戳。

I've done some research and the furthest I could get was thanks to How to add timestamp to STDERR redirection .我做了一些研究,我能得到的最远的结果是感谢How to add timestamp to STDERR redirection It redirects stdout but the timestamp added is of the time when the script finishes:它重定向stdout但添加的时间戳是脚本完成的时间:

#!/bin/bash
./server | ./predate.sh > log.txt

code of predate.sh : predate.sh代码:

#!/bin/bash
while read line ; do
    echo "$(date): ${line}"
done

It seems that server output is flushed after exit of the program.(without redirecting it works fine).似乎服务器输出在程序退出后被刷新。(没有重定向它工作正常)。 Also if I try using predate.sh on given example in mentioned thread, it works perfectly.此外,如果我尝试在提到的线程中的给定示例上使用predate.sh ,它可以完美运行。 I am aware it would be easy adding a timestamp to the main program but I would rather avoid editing its code.我知道向主程序添加时间戳很容易,但我宁愿避免编辑其代码。

I recently needed exactly that: receive log messages in a serial console (picocom), print them to a terminal and to a file AND prepend the date.我最近正好需要:在串行控制台 (picocom) 中接收日志消息,将它们打印到终端和文件,并在前面加上日期。

What I now use looks s.th.我现在使用的看起来很糟糕。 like this:像这样:

picocom -b 115200 /dev/tty.usbserial-1a122C | awk '{ print strftime("%s: "), $0; fflush(); }' | tee serial.txt
  • the output of picocom is piped to awk picocom的输出通过管道传输到awk
  • awk prepends the date (the %s option converts the time to the Number of seconds since 1970-01-01 00:00:00 UTC - or use %c for a human-readable format) awk在日期之前添加( %s选项将时间转换为自 1970-01-01 00:00:00 UTC 以来的秒数- 或使用%c为人类可读的格式)
  • fflush() flushes any buffered output in awk fflush() 刷新awk 任何缓冲输出
  • that is piped to tee which diverts it to a file.它通过管道传输到tee ,将其转移到一个文件中。 (you can find some stuff about tee here ) (你可以在这里找到一些关于tee东西)

moreutils ts moreutils ts

Absolute date and time is the default:绝对日期和时间是默认值:

$ sudo apt-get install moreutils
$ (echo a;sleep 1;echo b;sleep 3;echo c;sleep 2;echo d;sleep 1) | ts | tee myfile
$ cat myfile
Apr 13 03:10:44 a
Apr 13 03:10:45 b
Apr 13 03:10:48 c
Apr 13 03:10:50 d

or counting from program start with ts -s :或从程序开始计数ts -s

$ (echo a; sleep 1; echo b; sleep 3; echo c; sleep 2; echo d; sleep 1) | ts -s
00:00:00 a
00:00:01 b
00:00:04 c
00:00:06 d    

or deltas for benchmarking with ts -i :或使用ts -i进行基准测试的增量:

$ (echo a; sleep 1; echo b; sleep 3; echo c; sleep 2; echo d; sleep 1) | ts -i
00:00:00 a
00:00:01 b
00:00:03 c
00:00:02 d
$ (echo a; sleep 1; echo b; sleep 3; echo c; sleep 2; echo d; sleep 1) | ts -i '%.s'
0.000010 a
0.983308 b
3.001129 c
2.001120 d

See also: How to monitor for how much time each line of stdout was the last output line in Bash for benchmarking?另请参阅: 如何监视每行 stdout 是 Bash 中用于基准测试的最后输出行的时间?

Tested on Ubuntu 18.04, moreutils 0.60.在 Ubuntu 18.04、moreutils 0.60 上测试。

For Me Your Code is working perfectly fine对我而言,您的代码运行良好

Check this is what I tried检查这是我尝试过的

test.sh测试文件

#!/bin/bash

while true; do
  echo "hello"
done

predate.sh早于.sh

#!/bin/bash

while read line; do
  echo $(date) ":" $line;    
done

then然后

./test.sh  | ./predate.sh

gives me给我

Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello
Tue Jan 14 17:49:47 IST 2014 : hello

This can be redirected to some file using ">" or ">>" for append这可以使用“>”或“>>”进行附加重定向到某个文件

检查快照

Again, using ts from moreutils , you can just use exec at the top of your script.同样,使用moreutils ts ,您只需在脚本顶部使用 exec 即可。

#!/bin/bash

exec > >(ts>>file.log)

echo hello 1
echo hello 2
sleep 5
echo hello 3

If I understand your problem is to have stderr output included in your log.txt file.如果我理解您的问题是在 log.txt 文件中包含 stderr 输出。 Right ?对 ? If that's what you want the solution is:如果那是您想要的解决方案是:

./server 2>&1 | ./服务器 2>&1 | ./predate.sh > log.txt ./predate.sh > log.txt

Regards问候

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM