날짜 문자열은 true 내에서 업데이트되지 않습니다.

날짜 문자열은 true 내에서 업데이트되지 않습니다.

간단한 bash 스크립트가 있습니다.

#!/bin/bash

enp="$(ip route | grep "192.168.1.1" | cut -d' ' -f 3)"

while true; do
    vnstat -l -i "$enp" --style 4 --json | awk '{ print strftime("[%d/%b/%Y:%H:%M:%S]"), $0 }' >> raw/caching_server_network.json
    printf -- '-%.0s' {1..100}; echo "" >> raw/caching_server_network.json
    sleep 10
done

현재 이 스크립트는 각 vnstat 출력의 시작 부분에 strftime을 추가하고, 호출할 때마다 strftime이 업데이트됩니다. 산출:

[04/Jan/2022:13:31:17] {"index":1012,"seconds":2024,"rx":{"ratestring":"13.59 Mbit/s","bytespersecond":1698943,"packetspersecond":15220,"bytes":3397887,"packets":30441,"totalbytes":29895276777,"totalpackets":43496469},"tx":{"ratestring":"2.81 Gbit/s","bytespersecond":350918926,"packetspersecond":233842,"bytes":701837853,"packets":467685,"totalbytes":518923724379,"totalpackets":354639132}}
[04/Jan/2022:13:31:41] {"index":1013,"seconds":2026,"rx":{"ratestring":"206.68 Mbit/s","bytespersecond":25834765,"packetspersecond":31840,"bytes":51669531,"packets":63681,"totalbytes":29946946308,"totalpackets":43560150},"tx":{"ratestring":"3.15 Gbit/s","bytespersecond":394123782,"packetspersecond":269030,"bytes":788247565,"packets":538060,"totalbytes":519711971944,"totalpackets":355177192}}

내가 하고 싶은 것은 날짜/시간 문자열에 밀리초를 포함시키는 것입니다. 하지만 문제가 발생했습니다. 날짜 출력이 더 이상 업데이트되지 않습니다. 각 호출은 문자열에 동일한 시간을 추가합니다.

나는 다음을 시도했습니다 :

#!/bin/bash

enp="$(ip route | grep "192.168.1.1" | cut -d' ' -f 3)"

while true; do
    vnstat -l -i "$enp" --style 4 --json | awk '{ print "'"$(date +%F:%T.%3N)"'", $0 }' >> raw/caching_server_network.json
    printf -- '-%.0s' {1..100}; echo "" >> raw/caching_server_network.json
    sleep 10
done

산출:

04/Jan/2022:13:30:11.743 {"index":975,"seconds":1950,"rx":{"ratestring":"73.04 Mbit/s","bytespersecond":9130121,"packetspersecond":25590,"bytes":18260242,"packets":51181,"totalbytes":29368713172,"totalpackets":42315654},"tx":{"ratestring":"3.90 Gbit/s","bytespersecond":486961964,"packetspersecond":326200,"bytes":973923928,"packets":652400,"totalbytes":498158299423,"totalpackets":340676257}}
04/Jan/2022:13:30:11.743 {"index":976,"seconds":1952,"rx":{"ratestring":"12.23 Mbit/s","bytespersecond":1529119,"packetspersecond":17962,"bytes":3058239,"packets":35924,"totalbytes":29371771411,"totalpackets":42351578},"tx":{"ratestring":"4.18 Gbit/s","bytespersecond":522336815,"packetspersecond":346742,"bytes":1044673631,"packets":693484,"totalbytes":499202973054,"totalpackets":341369741}}

위 출력에서 ​​두 행의 날짜/시간이 어떻게 동일한지 확인하세요. 날짜 호출을 사용할 때 각 vnstat 호출에 대해 업데이트된 날짜를 어떻게 얻나요?

답변1

각 호출은 시간을 변경 vnstat하지만 vnstat여러 행이 출력되는 경우 모든 행은 동일한 시간을 수신합니다. 이는 쉘이 실행되어 date출력을 인수에 삽입하기 때문입니다 awk.

각 행에 대한 새 타임스탬프를 얻으려면 내 컴퓨터에 date타임 스탬프가 awk없으므로 vnstat더 간단한 예를 만들었습니다.

#! /bin/bash

while true; do
    for i in {1..3} ; do
        echo $i
        sleep .1
    done  | awk '{ system("date +%F:%T.%3N\\  | tr -d \\\\n"); print $0 }'
    printf -- '-%.0s' {1..80}; echo ""
    sleep 1
done

tr타임스탬프 뒤의 개행 문자를 제거합니다 .

답변2

쉘 루프를 사용하고 각 반복마다 awk유틸리티 date를 호출하는 대신 sleep(더 나쁘게는 명령 출력의 각 행을 호출하는 것) 대신 내부적으로 모든 작업을 수행할 수 있는 방식으로 모든 작업을 수행합니다 perl.

perl -MPOSIX -MTime::HiRes=gettimeofday -e '
  while (1) {
    open CMD, "-|", @ARGV;
    while (<CMD>) {
      my ($s,$us) = gettimeofday;
      printf "%s.%03d %s", strftime("%F:%T", localtime$s), $us/1000, $_
    }
    print "-" x 100 . "\n";
    sleep 10;
  }' vnstat -l -i "$enp" --style 4 --json >> file.log

또는 zsh:

zmodload zsh/zselect
ts_format='%D{%F:%T.%3.}'
sep=${(l[80][-])}

while true; do
  vnstat -l -i "$enp" --style 4 --json |
    while IFS= read -r line; do
      print -r ${(%)ts_format} $line
    done
  echo $sep
  zselect -t 1000 # cs
done >> file.log

관련 정보