Подтвердить что ты не робот

Как добавить метку времени при перенаправлении стандартного вывода в файл в Bash?

У меня есть программа (сервер), и я ищу способ (сценарий), который будет перенаправлять (или лучше дублировать) весь свой стандартный stdout в файл и добавлять метку времени для каждой записи.

Я провел некоторое исследование, и самое дальнее, что я смог получить, это благодаря тому, как добавить метку времени к перенаправлению STDERR. Он перенаправляет стандартный stdout но добавленная временная метка соответствует времени завершения сценария:

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

код predate.sh:

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

Кажется, что выход сервера сбрасывается после выхода из программы. (Без перенаправления он работает нормально). Кроме того, если я попытаюсь использовать predate.sh на данном примере в упомянутой теме, он работает отлично. Я знаю, что было бы легко добавить метку времени в основную программу, но я бы предпочел не редактировать ее код.

4b9b3361

Ответ 1

Мне недавно нужно было точно: получать сообщения журнала в последовательной консоли (picocom), печатать их на терминале и в файл AND дописывать дату.

То, что я сейчас использую, выглядит с. например:

picocom -b 115200 /dev/tty.usbserial-1a122C | awk '{ print strftime("%s: "), $0; fflush(); }' | tee serial.txt
  • вывод picocom подается на awk
  • awk добавляет дату (опция %s преобразует время в число секунд с 1970-01-01 00:00:00 UTC - или используйте %c для удобного для чтения формата)
  • fflush() удаляет любой буферный вывод в awk
  • который отправляется на tee, который отсылает его в файл. (вы можете найти информацию о tee здесь)

Ответ 2

moreutils ts

$ 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

или считая от запуска программы:

$ (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    

или дельты для бенчмаркинга:

$ (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

См. Также: Как отслеживать, сколько раз каждая строка стандартного вывода была последней выходной строкой в Bash для сравнительного анализа?

Проверено на Ubuntu 18.04, moreutils 0.60.

Ответ 3

Для меня ваш код работает отлично [/p >

Проверьте, что я пробовал

test.sh

#!/bin/bash

while true; do
  echo "hello"
done

predate.sh

#!/bin/bash

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

затем

./test.sh  | ./predate.sh

дает мне

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

Это можно перенаправить в какой-либо файл, используя " > " или " → " для добавления

Check Snapshot

Ответ 4

Опять же, используя ts из moreutils, вы можете просто использовать exec вверху вашего скрипта.

#!/bin/bash

exec > >(ts>>file.log)

echo hello 1
echo hello 2
sleep 5
echo hello 3

Ответ 5

Если я понимаю, что ваша проблема заключается в том, что в файл log.txt входит файл stderr. Правильно? Если это то, что вы хотите, это:

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

Привет

Ответ 6

Я использую приведенный выше пример:

$ picocom -b 115200/dev/tty.usbserial-1a122C | awk '{ print strftime("%s: "), $0; fflush(); }' | tee serial.txt

выгрузить/перенаправить выходные данные telnet в файл журнала, но я не могу запустить свой сценарий в фоновом режиме. Если я использую & для запуска в фоновом режиме, он не работает.


Точка № 1: Рабочая команда без &:
скрипт: dumpper.sh
$ telnet $1 $2 | awk '{ print strftime("%s: "), $0;}' | tee $host.$port.log;

команда: $./dumpper.sh 16.1.1.8 202


Пункт № 2: Не работает команда с &:
скрипт: dumpper.sh
$ telnet $1 $2 | awk '{ print strftime("%s: "), $0;}' | tee $host.$port.log 2>&1;

команда: $./dumpper.sh 16.1.1.8 20224 &

Ответ 7

Я выполняю работу cron следующим образом:

0 * * * * user /home/user/script.sh >>stdout.log

Тогда в script.sh, у меня есть что-то вроде этого:

#!/bin/bash
date
do_some_code

Поскольку "date" является частью stdout моего script.sh, метка времени является первой строкой в ​​каждой записи stdout.log.