Record every keystroke and store in a file
xinput test
can report all keyboard events to the X server. On a GNU system:
xinput list |
grep -Po 'id=\K\d+(?=.*slave\s*keyboard)' |
xargs -P0 -n1 xinput test
If you want to get key names from the key codes, you could post-process that output with:
awk 'BEGIN{while (("xmodmap -pke" | getline) > 0) k[$2]=$4}
{print $0 "[" k[$NF] "]"}'
Add > file.log
to store in a log file. Or | tee file.log
to both log and see it.
xinput
queries the XinputExtension of the X server. That's as close as you're going to get as a standard (I am not aware of any standard that covers X utilities) or common command to do that. That also does not require root privileges.
If the X server and xinput support version 2 of the XinputExtension, you can use test-xi2
instead of test
which gives more information, in particular the state of the modifiers (shift, ctrl, alt...). Example:
$ xinput test-xi2 --root
EVENT type 2 (KeyPress)
device: 11 (11)
detail: 54
flags:
root: 846.80/451.83
event: 846.80/451.83
buttons:
modifiers: locked 0 latched 0 base 0x4 effective: 0x4
group: locked 0 latched 0 base 0 effective: 0
valuators:
windows: root 0x26c event 0x26c child 0x10006e6
You can translate the keycode (in detail
) to a keysym with the help of xmodmap -pke
again, and the effective
modifier bitmask to something more helpful with the help of xmodmap -pm
. For instance:
xinput test-xi2 --root | perl -lne '
BEGIN{$"=",";
open X, "-|", "xmodmap -pke";
while (<X>) {$k{$1}=$2 if /^keycode\s+(\d+) = (\w+)/}
open X, "-|", "xmodmap -pm"; <X>;<X>;
while (<X>) {if (/^(\w+)\s+(\w*)/){($k=$2)=~s/_[LR]$//;$m[$i++]=$k||$1}}
close X;
}
if (/^EVENT type.*\((.*)\)/) {$e = $1}
elsif (/detail: (\d+)/) {$d=$1}
elsif (/modifiers:.*effective: (.*)/) {
$m=$1;
if ($e =~ /^Key/){
my @mods;
for (0..$#m) {push @mods, $m[$_] if (hex($m) & (1<<$_))}
print "$e $d [$k{$d}] $m [@mods]"
}
}'
would output:
KeyPress 24 [q] 0x19 [Shift,Alt,Num_Lock]
when I press Shift+Alt+q when num-lock is on.
Note that you don't need to have super-user privileges to install a program. If you have write access to somewhere on the file system where execute permission is granted (your home directory, /tmp
, /var/tmp
...) then you can copy an xinput
command from a compatible system there and execute it.
Have you considered using the script
command?