Linux shell: poll the keyboard button's state - linux

I have a script that is executed periodically in the background.
I want to prevent its execution if the Shift key is pressed.
The idea is to poll the keyboard's Shift button state, and if it's pressed — terminate the script immediately.
Any ideas? X server is allowed to use: I guess it will help.
UPD: I'm currently using this stupid hack:
[ $( sh -c 'cat /dev/input/by-id/usb-*kbd & sleep 0.5 ; kill $! 2>/dev/null' | wc -c ) -gt 1 ] && exit
The script just detects current keyboard events but does not distinguish them. 0.5sec is the kbd-events watch period. Not very nice, but still works :)

First off, you can monitor key up/down events, but as far as I know, there's no way to tell if the key is currently pressed. If you're OK with that, then...
That implies that the thing listening for the key event has to be running in another thread. The shell script will have to spawn a program in the background that listens for key events and sends a signal to the parent script on keypress. You can use trap to respond to the signal by exiting gracefully.
Check out KeyPress. It might give you a good start.
You may also be able to monitor /dev/input/eventN. This perl module may help.

Related

How to Stop & Start Screen Jobs Using Scripts in Linux

I want to use some scripts to stop and start a bunch of programs, each running in a separate linux screen. These programs run continuously and need to be stopped using Ctrl-C.
So I can write some code to stop a screen:
screen -S "mysessionname" -X quit
but do I need to send a Ctrl-C somehow first of all and if so then how?
Also, I can start a new detached screen thus from within a script:
screen -mdS "mysesssionname"
but how can I then kick of the job from within this screen using a script? I've tried attaching to the session and then starting the job all from within a script but it doesn't seem to work
Well let's hope that this can help you but to simulate the Ctrl-C in a script as far as i know you can use something like kill -3 and the pid of the process. See in manual of signals: "man 7 signal"

Sending keystroke to a process

I want to write a seperate program that can receive commands from network and replay these commands to omxplayer. omxplayer is the video player on raspberry pi, we can control omxplayer via the keystroke. May anyone please suggest some approaches that we can send keystroke event to a running process?
Any suggestions are appreciated. Thanks!
You can use FIFO to send keystrokes to omxplayer.
We'll show you a basic example of how you do it.
In Shell (Terminal 1),
mkfifo /path/to/dir/fifo
omxplayer /path/to/movie/dir/movie.ext < /path/to/dir/fifo
after you execute these commands, the terminal 1 will hold.
Now in terminal 2
echo -n . > /path/to/dir/fifo
now it will start play.
This was the basic example. You can create a php file to write to the fifo file. So from that you can send commands.
p will pause
q will quit
also, when using non-letter commands (like up arrow, and down arrow), you should send the correct key code.
Hope this helps.

shell script terminating program but not the script itself

I am using a shell script to automatically search network access points, and in airodump you use ctrl + c to stop the search, and I am wanting to it cancel the search but keep my shell script running. Since I am wanting to do user input after I am done searching for wifi networks. I tried to use trap, and it stops airodump, and my script.
I am just wanting to stop airodump wifi search and move onto my shell script of user input.
It's not entirely clear to me, but I believe you are wanting the user to be able to interactively stop the search via ctrl-C and then be prompted for input. This should do that:
#!/bin/sh
trap 'test "$airo" && kill -2 $airo' 2
airodump ... &
airo=$!
wait
unset airo
# Commands here will execute after the user hits ctrl-C to terminate the search

The GNU screen is unresponsive, seems blocked

GNU Screen seems to freeze. Unable to enter user input.
I was using GNU screen and when I pressed the screen it became unresponsive. I can execute all the GNU screen commands, but can't enter user input. I don't want to kill this screen as I have important work and I don't want to lose it.
In the commands below, replace Ctrl with whatever your escape key is for screen commands.
Try Ctrl+a q, which is the sequence to unblock scrolling.
Ctrl+a s is the sequence that blocks scrolling, which makes screen seem like it freezes.
When using PuTTY, you can get an apparently freezed screen if you press Ctrl+s.
This sends an Xoff signal blocking the terminal's output.
The solution is to press Ctrl+q to send the Xon signal.
The above works great if that is your issue.
This could also happen if you're ssh'd into another machine and haven't been to the window in awhile, then when you go back it's frozen. To fix this, you can try the following:
1) Create a new window
Ctrl-a c
2) ssh into the box where you ssh'd into the box in the window that's frozen.
3) Find the process the ssh is running under:
ps aux | grep <remote_box_on_frozen_screen>
or
ps aux | grep <your_user_id>
4) Kill the process
kill <process_id>
When you do screen -ls the first number of the screen name is the process id. So if the output is
There is a screen on:
21605.pts-0.Random-server (11/12/2017 11:44:15 PM) (Detached)
1 Socket in /var/run/screen/S-kg.
Then this will kill it:
kill 21605
Notice the number for the kill command is the same as in the screen -ls output.
If you are using backtick commands in status line - that is, if your .screenrc has something like this:
backtick 1 0 60 /some/script.sh
then you want to be sure that the script is fast: apparently backtick execution blocks all IO to screen.
If you make changes to the config, you'll need to restart the screen session (as the config applies only to new sessions).

How do I make my cygwin .xinitrc wait for the X server to exit?

I'm using Cygwin's startx and want to customize my xinitrc so that I don't get any "magic" X programs on screen, i.e., programs that will cause the X server to terminate if I exit them. I don't want any X programs to start up on screen at all, actually; I just want to use the XWin menu, customized from my .XWinrc .
Ordinarily from a .xinitrc, I would make the last line run the window manager. Then I can exit X by exiting the window manager from its own provided interface.
In this case, though my window manager and my server are effectively the same process, because I am using the XWin server. I don't have a windows manager to execute. I am starting the server from my .xserverrc file:
exec XWin -multiwindow -clipboard -silent-dup-error
I can sleep at the end of my .xinitrc, in a loop:
while [ 1 -eq 1 ]
do
sleep 10
done
But that seems inelegant.
I can wait for a child process, either by starting it up as the last line in my .xinitrc, or by starting it up earlier in the background and waiting for it explicitly with "wait {PID}". But I can't wait for the XWin.exe process, because it is a parent process of my .xinitrc script, not a child process.
I can't start up XWin.exe at the end of .xinitrc; if I try, I get a different window manager apparently starting up, with XWin not in rootless mode, and then I get an immediate shutdown.
Is there a more elegant way to do this than sleeping in a loop? Is there a way to start XWin from my .xinitrc and wait on it? Is there a way to tell the .xinitrc shell script to simply wait and not exit, without sleeping, such that it will continue executing and do nothing until XWin.exe exits? Is there something I should be starting in the background as the last line of my .xinitrc, so as to give me a process to wait on without starting up an X program?
So, summarizing from Ben Bullock's answer, the answer to "How do I make .xinitrc do this?" is "Don't!" Never ask "How do I use X to do Y?" questions. :) Skip startx/.xinitrc entirely.

Resources