0

How can I record keyboard actions with the timestamp, either to console, or preferably to a file?

I have showkey output like:

keycode  28 release
keycode  30 press
keycode  30 release
keycode  48 press
keycode  48 release

And I'd like it to be:

keycode  30 press 1551027529
keycode  30 release 1551027532
keycode  48 press 1551027534
keycode  48 release 1551027536
keycode  46 press 1551027542
keycode  46 release 1551027548
keycode  32 press 1551027549
keycode  32 release 155102751

I looked at How to modify output in bash command pipeline and have tried:

sudo showkey | awk -v date="$(date +%s)" '{print $1 date}'

And there is no output at all.

I've tried a while loop:

echo MY_PASSWORD | 
stdbuf -o0 sudo -S showkey |
while read line; 
do  

    echo "$line":$(date +%s)  >> /home/reedbear/user_scripts/output.txt; 


done

And my output shows the keypresses, but they all have the same time stamp, as I assume the while loop is evaluated with the full output of showkey when it is finished.

I don't know what stdbuf does, but I saw it somewhere last night. It does the same thing without it.

  • 1
    That while read loop looks like it should work, unless showkey insists on buffering the output. If you do showkey | cat, does the output come immediately, line-by-line? What about stdbuf -o0 showkey | cat? – ilkkachu Feb 24 at 17:35
  • sudo showkey | cat does not show output until it terminates (I stop pressing keys for 10 seconds) – Reed Feb 24 at 17:36
  • the stdbuf line does the same thing – Reed Feb 24 at 17:37
  • 2
    well, that would seem it doesn't lend itself nicely to being redirected to a pipe. Though the source code I can find in Debian seems to use printf as usual, so stdbuf should work on it. I don't have a machine at hand to test it, though. – ilkkachu Feb 24 at 17:46
  • Seems strange to me. I'm not well practiced with bash, though. Learned more today and last night than ever before lol. I'm now looking for other ways to listen to keyboard actions – Reed Feb 24 at 17:55
1
sudo showkey | awk -v date="$(date +%s)" '{print $1 date}'

This won't work, since you're running date once, before awk starts, so it will print the same value on all lines.

With GNU awk, you could use the systime() function to get the current time (in seconds since the Epoch). E.g. this works for me:

$ stdbuf -o0 showkey -a | awk '{ print $0, systime(); }'
 1551031085
Press any keys - Ctrl-D will terminate this program 1551031085
 1551031085
a        97 0141 0x61 1551031086
d       100 0144 0x64 1551031087
^D        4 0004 0x04 1551031088

(I can't test showkey with raw keycodes right now.)

  • I get the error awk: line 2: function systime never defined – Reed Feb 24 at 17:42
  • @Reed, with GNU awk. At least the on my Debian has systime() (GNU Awk 4.1.4), though the mawk I have doesn't. Something like `cmd | perl -pe 's/$/" " . time/e' would be another alternative – ilkkachu Feb 24 at 18:00
0

I gave up on showkey and switched over to xev.

xev -id $(xdotool search -name "Stardew Valley") -event keyboard >> /home/reedbear/user_scripts/output.txt

This gets me logs that look like:

KeyRelease event, serial 18, synthetic NO, window 0x260000a,
    root 0x1b0, subw 0x0, time 18101865, (893,683), root:(893,683),
    state 0x10, keycode 38 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (61) "a"
    XFilterEvent returns: False

KeyPress event, serial 18, synthetic NO, window 0x260000a,
    root 0x1b0, subw 0x0, time 18101865, (893,683), root:(893,683),
    state 0x10, keycode 38 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (61) "a"
    XmbLookupString gives 1 bytes: (61) "a"
    XFilterEvent returns: False

KeyRelease event, serial 21, synthetic NO, window 0x260000a,
    root 0x1b0, subw 0x0, time 18102365, (893,683), root:(893,683),
    state 0x10, keycode 38 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (61) "a"
    XFilterEvent returns: False

And then I use php, because I'm experienced with php, to pull the timestamp, keypress, and whether KeyRelease or KeyPress.

Then I'm using xdotool to send keypresses, but that's a separate thing.

I probably can do this without xdotool, but... I didn't.

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.