3

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.

Pandya
  • 24,618
  • 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 07 '15 at 07:33
  • @YoMismo su pandya -c "DISPLAY=:0 zenity --info" works! – Pandya Jan 07 '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 07 '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 07 '15 at 11:31
  • Note that if no X server is running, your script won't run at all. See also http://unix.stackexchange.com/questions/76335/udev-rules-involving-x11-dont-run-on-startup and http://unix.stackexchange.com/questions/80882/udev-running-a-shellscript-that-accesses-an-x-display – Gilles 'SO- stop being evil' Jan 07 '15 at 23:08

3 Answers3

4

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"'
eyoung100
  • 6,252
  • 23
  • 53
YoMismo
  • 4,015
  • Remove export because it gives error : -su: line 0: export: '--info': not a valid identifier – Pandya Jan 07 '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 07 '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. – CrimsonDark Feb 25 '19 at 09: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 '19 at 11:09
3

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.

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!"'
sMyles
  • 2,575