You are not logged in.

#1 2015-03-22 05:34:03

Xaero252
Member
Registered: 2011-11-28
Posts: 107

[Bash] Calculating number of keystrokes per second

I'm trying to write a script to monitor the overall number of keystrokes per second for a special application.
In the end I need to be able to monitor the current number of keystrokes per second and the all-time high.

I've tried a few different things so far, but what I've got so far (I'll be truncating the actual keycodes when I finalize this) is the following:

#!/bin/bash
#Turn of TTYecho for testing
stty -echo

#grab all keypress (ignore releases) and pass that data to fd3 timestamp is attached for logging
exec 3< <(xinput test 12 | xargs -IQ date "+[%Y-%m-%d %H:%M:%S.%N] Q" | grep press)&

count=0
while true; do
read <&3 line
if [[ "press" == *"$line" ]]
then
let count+=1
fi
sleep 1 && count=0 &
done

I'm sure I'm approaching this somewhat incorrectly, but I'm not sure why. I've tried many variations on this, and originally I was going to write to a log file and then parse that for each 1s window to grab the values but decided that was too slow.
Now what I'm running into is that no matter what I do, I run into two problems:
1.) The count variable is incremented regardless of actual physical keystrokes
2.) If the count variable does not, it will sit at 0 even though there are physical keystrokes until roughly 85 or more keystrokes have been made and then they will ALL increment as one big block.

I'm sure there's a better way of doing this but I'm completely overlooking it.

Offline

#2 2015-03-22 11:25:11

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,331
Website

Re: [Bash] Calculating number of keystrokes per second

I suspect you are running into issues at potentially various levels where I/O is buffered - also, what is $line?

But more on point, if you are using X-based tools anyways, just use Xlib, it would be much easier.

EDIT: also note that if you want any measure of accuracy, the bash approach will not work.  `Sleep' will wait for at least the number of seconds specified - there is no assurance of any degree of precision beyond that.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3 2015-03-22 16:45:39

Xaero252
Member
Registered: 2011-11-28
Posts: 107

Re: [Bash] Calculating number of keystrokes per second

I see, I had a feeling that i/o buffers were going to be my hitch
$line was actually undefined, I guess I overlooked that when I was restructuring the mess of code I had when I decided to ask for help into one of my half-working solutions. I'll probably have to fall-back on using python or something else then. I thought the sleep command we have here on Arch by default was compiled with the increased precision? I know that makes my usage case not very portable but since it will only ever be used on one system I don't think that'd be a huge deal. (I.E. you could pass MS to sleep) Either way, it wouldn't be as precise as doing it another way, so that kind of kills the idea for bash.

Offline

#4 2015-03-22 16:50:17

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,331
Website

Re: [Bash] Calculating number of keystrokes per second

Here's a start in C using Xlib:

/* compile: gcc -o key key.c -lX11 */

#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>

int main(int argc, const char **argv) {
	Display *dpy = XOpenDisplay(0x0);
	int scr = DefaultScreen(dpy);
	Window root = DefaultRootWindow(dpy);
	XEvent ev;
	XKeyEvent *kev;
	XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
	XGrabButton(dpy, 1, AnyModifier, root, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);

	char buf[64];
	while (!XNextEvent(dpy, &ev)) {
		if (ev.type == ButtonPress) break;
		else if (ev.type != KeyPress) continue;
		kev = &ev.xkey;
		XLookupString(kev, buf, sizeof(buf), NULL, NULL);
		/* change stderr below to a FILE * of a log file */
		fprintf(stderr,"%d\t%s\n", kev->time, buf);
		/* do something with key/buf here here */
	}

	XUngrabButton(dpy, 1, AnyModifier, root);
	XUngrabKeyboard(dpy, CurrentTime);
	XCloseDisplay(dpy);
	return 0;
}

"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

Board footer

Powered by FluxBB