Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

A script to measure idle time on input devices UNIX
I needed a quick shell script that would tell me how long the input devices attached to a system had been idle; I needed to perform maintenance, but could not when a user was interacting with it (it's a museum exhibit). Drew Thaler of Multisolar came up with the following. You can put it in your personal ~/bin directory, and remember to chmod it 755.
#!/bin/sh
echo $((`ioreg -c IOHIDSystem | sed -e '/HIDIdleTime/
 !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))
NOTE: Remove the line break from the above echo line (i.e. ...HIDIdleTime/!{...); it's been split here for a narrower display width.

Obviously, running this script directly from the command line will always evaluate to zero, but you can test it with a sleep command:
%> sleep 4; system_idle_time
4
Replace system_idle_time with whatever you named the script, of course. The returned value is in seconds; adjust the divisor accordingly for other time increments.
    •    
  • Currently 3.67 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (3 votes cast)
 
[12,594 views]  

A script to measure idle time on input devices | 7 comments | Create New Account
Click here to return to the 'A script to measure idle time on input devices' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
A script to measure idle time on input devices
Authored by: Jonas Lundberg on Apr 05, '04 02:45:54PM

This does not work in 10.2.8 for some reason. There might be some difference in the output format of the ioreg command but I haven't really checked that.



[ Reply to This | # ]
A script to measure idle time on input devices
Authored by: babbage on Apr 09, '04 11:09:43AM

Yes, the ioreg subsystem is keeping track of time differently between 10.2.x and 10.3.x. Observe a 10.2 machine:

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.2.8
BuildVersion:   6R73
$ sleep 2; ioreg -c IOHIDSystem | grep HIDIdleTime|sed 's#.*"HID#"HID#'
"HIDIdleTime" = <0000396da619284f>
"HIDIdleTime" = <0000396da64614ca>
"HIDIdleTime" = <0000396da67986cd>
"HIDIdleTime" = <0000396da71ab313>
$

And here's the same commands on a 10.3 machine:

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.3.3
BuildVersion:   7F44
$ sleep 3; ioreg -c IOHIDSystem | grep HIDIdleTime|sed 's#.*"HID#"HID#'
"HIDIdleTime" = 2930089953
"HIDIdleTime" = 2932857364
"HIDIdleTime" = 2935033969
"HIDIdleTime" = 2936912079
"HIDIdleTime" = 2939724019
"HIDIdleTime" = 2941758207
"HIDIdleTime" = 2943638209
"HIDIdleTime" = 2952352977

So on 10.3, the HIDIdleTime is pretty recognizable: move the decimal to the left 9 times and you get 2.9...., which is about right. On 10.2 on the other hand, the value seems to be about the same no matter how many seconds I sleep before letting the command run, and there's all those letters suggesting that the number is probably a hexadecimal value. Someone would have to figure out how to convert those numbers into the decimal representation in seconds, but I'm not sure how to do it yet.

For those that are interested, I've got a modified version of the script going:

$ cat ~/bin/osx_idle_time.sh
#!/bin/sh

echo -n "`date`: `uname -n` has been idle for "

secs=`ioreg -c IOHIDSystem | \
      awk '/HIDIdleTime/ {print $NF/1000000000; exit}' | \
      sed 's#\(\.[0-9][0-9]\)[0-9]*#\1#'`

echo "$secs seconds"

Which when run (on a remote machine, in this case), produces output like this:

$ ssh myhomemac.dyndns.org "~/bin/osx_idle_time.sh"
cdevers@myhomemac.dyndns.org's password: 
Fri Apr  9 11:06:42 EDT 2004: Myhomemac.local has been idle for 15650.6 seconds

Nice! Thanks for the idea!

---
--
DO NOT LEAVE IT IS NOT REAL

[ Reply to This | # ]

10.2
Authored by: mzs on Sep 05, '06 11:53:13AM
This should work in 10.2, it used to but I have made changes to the script since then:

#!/bin/sh

# Display idle time

foo='
/^[ |]*"HIDIdleTime" = / {
        # 10.2 and earlier uses CFData, later uses CFNumber
        if (substr($NF, 1, 1) == "<") {
                fmt="scale = 9; obase = 10; ibase = 16; %s / 3B9ACA00"
                v=toupper(substr($NF, 2, 16))
        } else {
                fmt="scale = 9; %s / 1000000000"
                v=$NF
        }

        line=sprintf(fmt, v)
        cmd="/bin/sh -c '\''echo \"" line "\" | bc'\''"
        cmd | getline line
        close(cmd)

        fmt="+%H:%M:%S"
        i=index(line, ".")
        if (i)
                fmt=fmt substr(line, i, 10)

        fmt=" '\''" fmt ", " line "s'\''"
        cmd="date -nur " line fmt
        cmd | getline line
        close(cmd)

        print line
        exit 0
}
'

ioreg -c IOHIDSystem | awk "$foo"
This gives nicer output like this:

% idletime 
00:52:04.493391248, 3124.493391248s
(I was ssh-ed in.)

[ Reply to This | # ]
A script to measure idle time on input devices
Authored by: bluehz on Apr 06, '04 09:02:01AM

Thx this is fantastic - I've been looking for just such a script for over a year. Could you give a god example of using this say on a fulltime basis to monitor and output without dragging the cpu down?



[ Reply to This | # ]
A script to measure idle time on input devices
Authored by: clith on Apr 06, '04 09:31:05AM
In Perl, that's:
ioreg -c IOHIDSystem | perl -ane 'if(/Idle/) {$idle=(pop @F)/1000000000; print $idle, "\n"; last;}'
sed just looks so ... awkward. :-)

[ Reply to This | # ]
easier with awk
Authored by: daniel_steffen on Apr 07, '04 04:30:54AM

FWIW, in this case, awk is actually easier than sed or perl IMO...

ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print $NF/1000000000; exit}'


[ Reply to This | # ]
A script to measure idle time on input devices
Authored by: magir on Jan 01, '06 09:50:28AM
To let the script run endlessly simply surround the statement by "until":

#!/bin/sh
until false
do
  echo $((`ioreg -c IOHIDSystem | sed -e '/HIDIdleTime/ !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))
  sleep 1
done
                                                                                                                        


[ Reply to This | # ]