Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux and bash - How can I get the device name of an input device event?

Tags:

linux

bash

I'm trying to automate the process of getting a game controller's device event and checking its name, then if the name matches a string, pass the event to another program.

By hand, I run evtest /dev/input/eventXX to check the name of the input device, then keyboard interrupt(ctrl-c) to stop it. If that device matches the name of a certain type of game controller, I run the command xboxdrv --evtest /dev/input/eventXX with the same event number.

However, because the "evtest" command continues to print the input device's outputs instead of terminating after printing the name and only exits on keyboard interrupt, I'm not sure how I could have the bash script get the name of the device.

I'm still learning bash so there may be syntax errors in my code. But, here it is:

#!/bin/sh
WiiUGCName="Wii U Gamecube Adapter Port"

#find the controller(s)
NumberOfEvents=$(ls /dev/input | grep -c event*)

echo "Number of input devices: $NumberOfEvents"

#launch xboxdrv for each controller
i=0
while [ $i < $NumberOfEvents ]; do
    echo "loop"
    OccurrencesOfName=$(evtest /dev/input/event$i | grep -c "$WiiUGCName")
    echo "Occurrences: $OccurrencesOfName"
    if [ $OccurrencesOfName>0 ]; then
        echo "Controller found"
        #launch xboxdrv here
    else
        echo "no controller found"
    fi
    let i=i+1
done

All this code actually does right now is hang at that evtest since it cannot be terminated.

like image 502
William Weissman Avatar asked Oct 24 '25 05:10

William Weissman


2 Answers

The simplest option is to give evtest some reasonable time to print the interesting portion of the output, say 1 second, and then kill it. If you place that code in a shell function, the resulting code can remain readable. For example, replace:

OccurrencesOfName=$(evtest /dev/input/event$i | grep -c "$WiiUGCName")

with the invocation of a shell function:

OccurrencesOfName=$(evtest_and_exit | grep -c "$WiiUGCName")

evtest_and_exit can be defined as follows:

evtest_and_exit() {
    local evtest_pid
    evtest /dev/input/event$i &
    evtest_pid=$!
    sleep 1  # give evtest time to produce output
    kill $evtest_pid
}
like image 56
user4815162342 Avatar answered Oct 26 '25 20:10

user4815162342


There seems to be a much easier way now. Each device is added to /sys/class/input/ so you can run code like this:

NumberOfEvents=$(ls /dev/input | grep -c event*)

i=0
while [ $i -lt $NumberOfEvents ]; do
    Name=$(cat /sys/class/input/event$i/device/name)
    echo event$i $Name
    let i=i+1
done

Which should print an output like this:

event0 vnc-keyboard
event1 vnc-abspointer
event2 vnc-relpointer
event3 Xbox Wireless Controller

Alternativly if you don't mind using python3

import evdev #python3 -m pip install evdev

for device in [evdev.InputDevice(fn) for fn in evdev.list_devices()]:
    print(device.fn, device.name, device.phys)

like image 28
John Avatar answered Oct 26 '25 19:10

John