You have two main ways to tackle this.
Redirect a stdin from a tty to your application
By default systems boot to tty1, you can disable the getty running on that tty and hijack its input for your on purpose. First disable the getty on the system
sudo systemctl stop getty@tty1.service
sudo systemctl disable getty@tty1.service
You should do this from an ssh session or another getty or you will lose your login. You didn't mention your system, but with systemd this is the way - consult your distros documentation if this does not work for you
Now we need to create a wrapper script that contains your application to redirect /dev/tty1
to stdin of your program (the </dev/tty1
at the end): /usr/local/bin/rxtxcomm
#!/bin/bash
/usr/bin/java -Djava.library.path=/usr/lib/jni \
-cp /usr/share/java/RXTXcomm.jar -jar '/foo/bar.jar' </dev/tty1
And make it executable with:
sudo chmod +x /usr/local/bin/rxtxcomm
Then update your service file to run this script instead. Restart the service and it should attach its stdin to /dev/tty1
.
You can try it manually by running the above command in another tty or ssh session, but you need to run it as root (or changes the permissions on the tty). Note that with this solution you have to be on tty1 for it to capture any input (alt+ctrl+F1 on most systems). Also, to do this you must be root (which service files are by default) or the user you run as must have access to read from the tty directly.
Read directly from /dev/input/
Almost all devices in linux are available as files inside /dev
. Keyboards are available in /dev/input/
. You can modify your program to instead read directly from these files - the can be read from like any files but produce binary data so it is a little more work to get the characters typed.
Here is a short java example taken from this stack overflow question.
// replace path with path from your system
DataInputStream in = new DataInputStream(
new FileInputStream("/dev/input/by-id/usb-0430_0005-event-kbd"));
String map = " abcdefghijlkmnopqrstuvwxyz ";
// sizeof(struct timeval) = 16
byte[] timeval = new byte[16];
short type, code;
int value;
while (true) {
in.readFully(timeval);
type = in.readShort();
code = in.readShort();
value = in.readInt();
System.out.printf("%04x %04x %08x %c\n", type, code, value,
map.charAt(value>>>24));
}
This method has the advantage of attaching to a specific keyboard - so you can attach another keyboard without interfering with the script. Which can be useful for debugging the system. It also means you do not need to disable a tty or forced to be on a specific tty for the application to work. You are still required to run as root however, or changes the permissions of the devices so another user has direct access to it.
dpkg-reconfigure keyboard-configuration
)? You should read more documentation about your barcode reader! – Basile Starynkevitch Sep 19 '17 at 09:09