sh: Detect key (CTRL/SHIFT/CAPS LOCK) state?

I'm trying to write a shell script that runs periodically and if I'm not at the keyboard, it should do one thing, but if I am at the keyboard, it should do another thing. Therefore I've decided that it would be good if I could press down the CTRL key, (or some other key) and have the shell script detect the key state. I can't use "read" because the script will stop and wait for input, and I can't enter anything if I'm not at the keyboard.

You could try test -t to determine if stdin is a terminal (helps to identify if you running from cron (or piping input):

 if [ -t 0 ]
then
      echo "Stdin is a terminal
fi

You could add a command line option to the script to prompt from data (or not), eg -b flag for batch mode.

If you really want to read the keystate under and you're using X11 you can use the xset -q command to query a number of things, including the keyboard LED mask. This is pretty hardware/system dependant and will probably not work over ssh connections, with character terminals or windows vt* terminal emulators, etc.

None of those solutions will work. It's an initramfs script I'm working on, so there will no X11. I guess there is no simple solution to my problem. Thanks anyway.

So, I made this code, but it's not working and I have no idea why.

#!/bin/sh

read VAR < /dev/input/event3

if [ -n "${VAR}" ]; then
  echo "Key pressed"
else
  echo "No key pressed"
fi

If I do something like 'cat /dev/input/event3' and press some keys, I get all sorts of garbage on the screen, so I know I can get output from the keyboard, but when I run the script '$VAR' stays empty. If I use a regular non-empty file or some other device, (like the hard disk) the script works.

I'm totally stumped.:wall: Any help would be much appreciated.

Clearly /dev/input/event3 is not a text file and therefore not suitable for reading with a Shell read. In fact there is little of interest to Shell programmers under /dev. (Yep I know about /dev/null etc.).
Be very very careful in /dev - it is remarkably easy to destroy your system.

What is the output from:

ls -lad /dev/input/event3
file /dev/input/event3

(Googling the device suggests that it might be a keyboard device on some versions of Linux - a fact of little use to Shell programmers).

What Operating System and version are you running?
What Shell are you running?
What are you trying to do? Can you explain the Project in words just in case there is a stock solution?

There will be kernel driver software between Shell and a keyboard.
If you have "bash" there is a Shell raw "read" with a timeout but even then it will not register keys like ctrl and shift as characters. Reading characters in a tight loop without timeout is CPU-intensive.

A common way to modify the behaviour of a cleverly designed running Shell script is to create a flag file or to use a Shell "trap" to react to a keyboard control code or signal.

What is an "initramfs script", what does it do, and why would you want to interrupt it?

Is it like this:
http://en.wikipedia.org/wiki/Initrd

What runstate are you in while this script is running?

Now, here's my problem. I'm trying to unlock my encrypted system disk in Ubuntu 10.10. Sometimes I want to enter the passphrase via SSH and sometimes locally. Here's the piece of code that needs to be modified.

if [ -x /bin/plymouth ] && plymouth --ping; then
  cryptkeyscript="plymouth ask-for-password --prompt"
  cryptkey=$(echo -e "$cryptkey")
else
  cryptkeyscript="/lib/cryptsetup/askpass"
fi

I need the script to run the first case if I want to enter the passphrase via the local keyboard, and run the second case if I want to enter the passphrase via SSH.

if [ -x /bin/plymouth ] && plymouth --ping && #I'm at the keyboard#; then
  cryptkeyscript="plymouth ask-for-password --prompt"
  cryptkey=$(echo -e "$cryptkey")
else
  cryptkeyscript="/lib/cryptsetup/askpass"
fi

 

So, how do I notify the computer that I am at the keyboard? By pressing a key, perhaps.

Does "at the keyboard" mean "on the console" ?

This post is very difficult to understand for some reason. Maybe I'm being thick.

This implies a regular cron job or some other automated job (hence the reply in post #2). This is clearly? not the case.

Best I can suggest is running the unix command "tty" when "at the keyboard". Hopefully it will reply "/dev/console". If it does, we have a simple way of distingishing where we are.

Btw. It would really help if you answered the questions.

Ah, now things are becoming clearer! You are using Plymouth for graphical boot animation and shutdown.

As far as I recall, to do what you want will require some actual C coding. You need to register a callback using ply_window_add_keyboard_input_handler() to get called whenever a user types something. Also note that Plymouth deliberating stops watching for keyboard input at certain times.

It is a while since I looked under the hood at the Plymouth source code but I do not think things have change much since then as I do not see much traffic on the Plymouth mailing list.

1 Like

(Signing off from this post).