I'm using for nicstat this command

while true; do nicstat -eth1 1 60 > log-$(date +%F-%T).txt; done

this command creates log file for each 60 seconds of my ethernet interface, the problem is the files are not for each clock minute, when running this command the first log file created can be some thing like log-12:00:04.txt "containing values from second number 4 in this minute ending with second number 3 in the next minute" also if it was not so precisely stared at the beginning of the minute, after a while I start to have seconds step up like log-12:14:05.txt, then after some minutes log-12:32:06 ...etc.

I need a file for each clock minute containing values for each scecound from 00 till 59 like: log-12:00:00.txt, log-12:01:00.txt, log-12:02:00.txt, etc.

  • Is cron an option? – dhag Mar 15 '17 at 20:55
  • cron never worked for me , tried * * * * * nicstat -eth1 1 60 > log-$(date +%F-%T).txt , also saved the command in a shell file and tried * * * * * /home/nicstatcode.sh – Hossam Zalabany Mar 15 '17 at 21:01
  • I'm not clear on the problem; is it that the nicstat command sometimes takes longer than 60 seconds to run, and so your logs end up with non-zero seconds in their name? Or that the format for the date command isn't giving you what you want? – Jeff Schaller Mar 16 '17 at 1:23
  • Thanks for reply, to start the command for first time, I need to precisely start it in a 00 second clock otherwise the output will not start with the 00 values. also milliseconds count, that makes the frequency after while step 1 second and I start have files named 'log-12:41:01.txt' then after another while it steps again to be 'log-12:54:02' – Hossam Zalabany Mar 16 '17 at 9:54
  • I edited the post to clarify ... thanks for your comment :) – Hossam Zalabany Mar 16 '17 at 10:04

With zsh:

#! /bin/zsh -

zmodload zsh/datetime # for $EPOCHREALTIME/strftime...
zmodload zsh/zselect  # for sub-second sleeps
zmodload zsh/mathfunc # for int()

# wait till start of the next minute at first
for ((next = (EPOCHSECONDS / 60 + 1) * 60;; next += 60)) {
  (( sleep = int((next - $EPOCHREALTIME) * 100) ))
  (( sleep <= 0 )) || zselect -t $sleep
  strftime -s now %T $next
  nicstat -i eth1 1 60 > log-$now.txt &

I did add a & to run nicstat asynchronously on the assumption that nicstat 1 60 would take slightly over one minute to run. Then if we ran it synchronously (that is without the &), it would start to drift. Here we make sure nicstat is started exactly every minute.

However nicstat 1 60 takes slightly over 59 seconds to run, not 60, as the first line it displays is not the statistics for 12:00:00 to 12:00:01, but the overall statistics since boot (or since the statistics were last reset). And the second line (labelled 12:00:01) is for the statistics for 12:00:00 to 12:00:01 (and the 60th line after 59 seconds labelled 12:00:59 is for the statistics from 12:00:58 to 12:00:59).

The statistics for 12:00:59 to 12:01:00 will be missing. So you may want to change it to nicstat 1 61, so that the output contains 61 lines, the first one for the statistics since boot and the next 60 ones for the statistics of each second in that minute.

As another approach to your problem, you could run just one nicstat and have awk split its output into log files:

nicstat -i eth1 1 | awk '
  NR == 1 {header = $0; next}
  !/^[012]/ {next} # skip other headers
    log = "log-" substr($0, 1, 6) "00.log"
    if (log != last_log) {
      if (last_log) close(last_log)
      print header > log
      last_log = log
    print > log

This time, except for the first non-header line of the first file, each entry will be the statistics for the past second.


If you don't need sub-second accuracy, the simple solution would be something like:

while true ; do 
    sleep $[ 60 - $(date +%s) % 60  ];

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.