2

I have a device that connects via USB when a button is pressed. It immediately ceases the connection, when the button is released. I want to start a graphical application when I press this button.

I could successfully access the button and start the application. The problem is that when I press the button multiple times, the application restarts again and again after being closed, because udev apparently queues the events or holds them until they can be processed.

So I wrote a bash script that checks whether the application is running. When it is not running it starts the application. When it is running it maximizes the application. Here the same problem occurred, so I tried to start the application in the background with &, but then it is killed when the udev rule has finished. Same with nohup

Maybe a bash script is not the best way here. I need a script that can start a long-term application in a separate process, so the script can finish and be run again. It should, if possible, also be a Linux native method, so I don't have to install more dependencies.

I found this thread How to run long time process on Udev event? that deals with the same problem. He appearently solved it with using cmd | at now, but this commands seems to be deprecated, since cronie doesn't have this command like cron did.

I just found out that at is a package you need to install, but then the application also starts multiple times and the script doesn't finish.

I am running Manjaro, so basically Arch.

neolith
  • 243
  • Note that at isn't part of cron, you just need to make sure it is installed and that the atd daemon is running. Please [edit] your question and add your OS information if you need help with that. – terdon Sep 25 '20 at 13:13
  • Just found that out myself, but at does also not solve the problem. I edited the description. – neolith Sep 25 '20 at 13:15
  • Related https://unix.stackexchange.com/q/611115/377345 – AdminBee Sep 25 '20 at 13:15
  • @AdminBee Is it okay that I posted this as a general question now? I don't want to spam, but sometimes I think it is better to ask the question in a better way to get solutions. Also this is better for the community than bascally demanding from people to fix my code. – neolith Sep 25 '20 at 13:20
  • 1
    It's absolutely fine! As you said, the general question is useful but so is your more specific one about your code. Both are welcome! AdminBee simply linked the other question since it provides useful context. – terdon Sep 25 '20 at 13:23
  • @neolith I personally think it's ok. A moderator may decide that this obsoletes the original question and recommend that that one be deleted, but I just wanted to provide context. – AdminBee Sep 25 '20 at 13:23
  • Okay thanks. This is really a tricky thing to do. I also tried messing with systemd and got it to work, but a service is not intended to stop immediately, so it was also not the solution. – neolith Sep 25 '20 at 13:27
  • You should look into using the flock utility, e.g. flock -n /path/to/script /path/to/script, if you don't want to have a "storm" of processes running your script at the same time. –  Sep 25 '20 at 16:22
  • That will not solve my problem. The script has to run till the end and with flock I will just prevent it from queueing up. – neolith Sep 27 '20 at 09:25
  • Just tested it out @user414777. It doesn't prevent udev from queuing up events. – neolith Sep 27 '20 at 09:58
  • That was a hint. You were supposed to read the manpage. man 1 flock. If you an instance of your script to wait until the previous has finished, you're using flock without -n. –  Sep 27 '20 at 12:34

1 Answers1

0

To solve the problem of udev queues the events I use RUN+="/local/run.sh /local/main-script.sh" where run.sh contains

#!/bin/bash

echo $1 | at now

You need sudo apt-get install at first.

To avoid multiple runs you need something like

if [ -f /opt/running_on ]; then
    exit
else
   echo run > /opt/running_on
   # put your commands here
   sleep 10
   rm /opt/running_on
fi
oat
  • 62
  • That's racy. I suggest, like I already did to the OP, that you have a look at the flock(1) utility. –  Sep 25 '20 at 16:25
  • @oat Your solution does not call the script. It doesn't work at all. – neolith Sep 27 '20 at 10:06
  • It works now. It should have been pointed out that atd has to be started via systemctl enable atd --now – neolith Sep 27 '20 at 10:53