50

I am a newbie to linux and I am trying to watch a command and try to log it into a file. I tried

watch -t -n 10 "(date '+TIME:%H:%M:%S' ; ps aux | grep "pattern" | wc -l)" >> logfile

and am expecting a result like

TIME: 10:32:30    12
TIME: 10:32:40    18
TIME: 10:32:50    2

to be stored in logfile. However, when the logfile has unprintable characters in in. How do I get this kind of output from the command li

LoudKur
  • 653

8 Answers8

70

This can easily be done using watch too without using any scripts.

watch -t -n 10 "(date '+TIME:%H:%M:%S' ; ps aux | grep "pattern" | wc -l) | tee -a logfile"

36

In order to do what you are looking for, a simple script (as @Ignacio pointed out) should do the trick:

while true
do
    echo "$(date '+TIME:%H:%M:%S') $(ps aux | grep "pattern" | wc -l)" | tee -a logfile
    sleep 2
done

I use tee instead of >> so that you can see the output on your terminal as well as capture it in your log.

Kirk
  • 2,472
24

watch is meant for output to a display. If you simply want to run a command every X seconds then you should just use a delay loop for that.

while true ; do somecommand ; sleep 2 ; done
7

watch is an ncurses program, and is designed to be run in a console window (not redirected), which is why it's creating a bunch of unprintable characters (those are the control characters that manage and move the cursor around for redrawing the screen).

You might try moving the date / grep commands into a script, and then call that script from a cronjob.

Darth Android
  • 38,658
5

Ok, so I put it in a script and have the following code:

#!/bin/sh
NOW=$(date '+%Y%m%d%H%M%S')
LOGFILE="log.$NOW"

while true
do
    echo $(date '+[TIME: %H:%M:%S]   Output: ' ; ps aux | grep "pattern" | wc -l ) | tee -a $LOGFILE
    sleep 2
done
LoudKur
  • 653
2

One easy alternative would be putting the command in a cmd.sh file with the following content:

#!/bin/bash
(date '+TIME:%H:%M:%S' ; ps aux | grep "apache" | wc -l) >> logfile

And then just run:

watch -t -n 10 ./cmd.sh
1

I came across this question when I was trying to get better/logged output from du -sh $data_path. I used the "while command, do sleep" pattern found here, but used some complex AWK to give the output I wanted.

while du -sh $data_path; do sleep 1; done | awk '
$1 != size {
    size=$1;
    path=$2;
    time=systime();
    seconds=time-prevtime;
    if(seconds < 1000000000){
        seconds=seconds" seconds"
    }else{
        seconds=""
    }
    print size, path, strftime("%m/%d/%Y@%H:%M:%S", time), seconds; 
    prevtime=time
}'

I actually did this as a oneliner, which is why there are semicolons. But to make it readable, I broke it out. The output looks like:

502G /var/lib/cassandra/dump/ 05/22/2018@04:46:17
503G /var/lib/cassandra/dump/ 05/22/2018@04:46:59 42 seconds
504G /var/lib/cassandra/dump/ 05/22/2018@04:47:57 58 seconds
505G /var/lib/cassandra/dump/ 05/22/2018@04:48:55 58 seconds
506G /var/lib/cassandra/dump/ 05/22/2018@04:49:53 58 seconds
507G /var/lib/cassandra/dump/ 05/22/2018@04:50:50 57 seconds
508G /var/lib/cassandra/dump/ 05/22/2018@04:51:46 56 seconds
509G /var/lib/cassandra/dump/ 05/22/2018@04:52:44 58 seconds
510G /var/lib/cassandra/dump/ 05/22/2018@04:53:41 57 seconds
0

Here is an example I just needed for a watch on a ps axf with a timestamp at the bottom of the entire output. I am watching for when Apache fails. I had to pipe to tee for each command, the ps and the date.

watch 'ps axf | grep --line-buffered "[a]pache2"| tee --append logfile-apache-issue.log; date '+TIME:%H:%M:%S' | tee --append logfile-apache-issue.log'

Sample Output of tail --follow logfile-apache-issue.log on the resulting file.

29862 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29863 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29864 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29865 ?        S      0:00          \_ /usr/sbin/apache2 -k start
26635 pts/2    S+     0:00  |       \_ tail -n 1000 -f /var/log/apache2/error.log
TIME:02:21:13
13622 ?        SN     0:33      \_ /usr/sbin/apache2 -k start
25038 ?        Ss     0:01      \_ /usr/sbin/apache2 -k start
29859 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29860 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29861 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29862 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29863 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29864 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29865 ?        S      0:00          \_ /usr/sbin/apache2 -k start
26635 pts/2    S+     0:00  |       \_ tail -n 1000 -f /var/log/apache2/error.log
TIME:02:21:15
13622 ?        SN     0:33      \_ /usr/sbin/apache2 -k start
25038 ?        Ss     0:01      \_ /usr/sbin/apache2 -k start
29859 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29860 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29861 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29862 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29863 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29864 ?        S      0:00          \_ /usr/sbin/apache2 -k start
29865 ?        S      0:00          \_ /usr/sbin/apache2 -k start
26635 pts/2    S+     0:00  |       \_ tail -n 1000 -f /var/log/apache2/error.log
TIME:02:21:16
Elijah Lynn
  • 1,602