0

I found several questions on http://unix.stackexchange.com & on http://stackoverflow.com related to launch script by udev rules. But I can't find exact solution or certain answer for executing Bash script.

So, I'm asking the (canonical) question: How to run/launch/execute Bash script by means of udev rules?

Another thing that I found on Writing udev rules is:

udev does not run these programs on any active terminal, and it does not execute them under the context of a shell. Be sure to ensure your program is marked executable, if it is a shell script ensure it starts with an appropriate shebang (e.g. #!/bin/sh), and do not expect any standard output to appear on your terminal.

Hence, I want to know if possible that "How to run bash script by udev rules?"


Here is simple example of executing bash-script.

I've written 99-myrule.rules under /etc/udev/rules.d which contains:

ACTION=="add", ATTR{idVendor}=="0781", ATTR{idProduct}=="5567", RUN+="/home/pandya/example.sh"

I found Vendor & Product ID from lsusb output:

$ lsusb | grep SanDisk
Bus 001 Device 066: ID 0781:5567 SanDisk Corp. Cruzer Blade

And I want to execute experimental command zenity --info when my pendrive (of SanDisk listed above) attached.

so, I've writted /home/pandya/example.sh (which is called from RUN+= in udev rules) contians:

#!/bin/bash
zenity --info &
exit

But This script is not executing (in-spite of having execution permission). I've also tried following:

  • export DISPLAY=:0 in script before zenity --info
  • bash -c 'DISPLAY=:0 zenity --info

And of-course:

  • sudo restart udev
  • sudo udevadm control --reload-rules

But I can't get output zenity --info.

Hence How can I run Bash script by menas of udev rules? Suggest me if I'm missing anything.

  • Most probably it is executing but doesn't know where to show the output. I guess you are being logged in to X with a user different than root, and that rule is most probably being run as root. Have you tried running su - your_X_user_here -c 'export DISPLAY=:0 zenity --info'? – YoMismo Jan 7 '15 at 7:33
  • @YoMismo su pandya -c "DISPLAY=:0 zenity --info" works! – Pandya Jan 7 '15 at 10:13
  • @YoMismo All bash script can be executed by su <username> -c "DISPLAY=:0 bash -c /path/to/script.sh" is the answer – Pandya Jan 7 '15 at 10:18
  • Ok, I'll put the comment as an aswer so that you can mark it as solved and others can benefit from it. By the way, be aware of the '-' before the user. You may have problems in other contexts, since the '-' loads the user variables and if it is not set in the command those variables won't be loaded. – YoMismo Jan 7 '15 at 11:31
  • Note that if no X server is running, your script won't run at all. See also unix.stackexchange.com/questions/76335/… and unix.stackexchange.com/questions/80882/… – Gilles Jan 7 '15 at 23:08
2

Most likely, the command is executing but doesn't know where to display the output. I assume you are being logged in to X with a user other than root, and that rule is most likely being run as root. Try the following command:

su - your_X_user_here -c 'export DISPLAY=:0;zenity --info'

For running any Bash Script follow the command:

su - your_X_user_here -c 'export DISPLAY=:0; bash -c "/path/to/script.sh"'
  • Remove export because it gives error : -su: line 0: export: '--info': not a valid identifier – Pandya Jan 7 '15 at 14:01
  • export works fine, the semicolon was missing. It may not be necessary but if you do it the variable is exported. – YoMismo Jan 7 '15 at 14:12
  • I have the same problem, but it is not apparent to me what the answer means. Where exactly should the suggested command be run? Is it something to type into an arbitrary terminal window which then affects whatever else is happening on the computer, or is that su - your_X_user_here ... command to be entered as the command in the rules files at the `RUN += ..." point ... or somewhere else? A little additional guidance would be most appreciated. – user02814 Feb 25 at 9:38
  • @user02814 you can either run the first command in your RUN+= or pack your commands on a shell script and run them using the second one in your RUN+=. – YoMismo Feb 25 at 11:09
0

For anybody else reading this, the only way I was able to get my script in Kali Linux 2016 to work, was like this:

#!/bin/bash
set -x
xhost local:root
export DISPLAY=:0.0
su root -c 'zenity --notification --text="I am a notification!"'
0

I recently found an elegant way to display GUI or X task from udev rules without being worried about DISPLAY. The principle would be the same for Shell scripts using export.

IMPORT{program}="/usr/bin/xpub", \
RUN+="/bin/su $env{XUSER} -c '/usr/bin/notify-send Hello'"

$env{ENV}: if the current-tty-user starts X, otherwise remove it for root.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.