Page 1 of 3 123 LastLast
Results 1 to 10 of 28

Thread: Run an shell script via a udev rule

  1. #1

    Default Run an shell script via a udev rule

    Hi
    I'm quite new with OpenSUSE, but I'm used to another distro from the RPM family : Fedora.
    I used it for several years, but now I'm working on a development project.

    I am using OpenSUSE Leap 42.3 on my laptop, and am working on a program that will detect when a CD/DVD drive is inserted or removed.
    For now what I achieved is to have a udev rule that launches a bash script, and this script logs output to a log file.
    I can successfully read the entries in this log file, the disc insertion/removal is logged correctly.

    /etc/udev/rules.d/autodvd.rules :
    Code:
    SUBSYSTEM=="block", ENV{ID_CDROM}=="?*", 
    ENV{ID_PATH}=="pci-0000:00:1f.2-scsi-0:0:0:0", ACTION=="change", 
    RUN+="/usr/local/bin/autodvd"
    /usr/local/bin/autodvd :
    Code:
    #!/bin/bash
    {
      echo "ENTER SCRIPT"
      if [ "$ID_CDROM_MEDIA" = "1" ]; then
        echo "$(date)    DISC INSERTED"
      else
        echo "$(date)    DISC EJECTED"
      fi
    } &>> "/var/log/autodvd.log" &
    An example of the output I got in this log file :
    Code:
    ENTER SCRIPT
    Fri Feb  9 23:40:44 CET 2018    DISC EJECTED
    ENTER SCRIPT
    Fri Feb  9 23:40:58 CET 2018    DISC INSERTED
    ENTER SCRIPT
    Fri Feb  9 23:41:28 CET 2018    DISC EJECTED
    ENTER SCRIPT
    Fri Feb  9 23:41:28 CET 2018    DISC EJECTED
    What I want to do next is to launch a SH script when the disc is inserted/removed, so I tried to add a line like this one
    Code:
    sh /home/jean/some-script.sh
    just after the "echo" command, either for the insert or ejected case, but I can't get it to work.
    For instance, if i used this shell script to launch an instance of firefox or leafpad, the application is launched if I run the script from terminal.
    But nothing happens when I try to call the shell script from my "autodvd" script.

    I'm quite new to bash/shell scripting, and completely new to udev rules, so I'm sure I'm missing something important.
    Could you please help me on this topic ?

    Any help will be greatly appreciated

  2. #2

    Default Re: Run an shell script via a udev rule

    Hi,

    First of all you can remove the sh in front of your script, if it is a bash script. The extension .sh is a personal choice but it is not needed as well.

    It has been a while but I have done something like that in the past and i found my answer here.

    Code:
    https://unix.stackexchange.com/questions/177897/run-a-script-that-displays-an-x-window-from-an-udev-rule
    It states the use of

    Code:
    su - username -c .....
    So udev knows which user is running the script and where to display the output.

    As an side note leap has bash4 and has an additional feature for the builtin printf that can display time/date.

    An example of printing date and time.
    Code:
    printf '%(%Y-%m-%d %H:%M:%S)T %s' -1
    the format is supported by strftime.

    For your use case, you can probably use.
    Code:
    printf '[%(%Y-%m-%d %H:%M:%S)T] %s ' -1 'Disc Inserted'
    One advantage of that code is that it does not fork the date utility.
    "Unfortunately time is always against us" -- [Morpheus]

    .:https://github.com/Jetchisel:.

  3. #3
    Join Date
    Jun 2008
    Location
    Auckland, NZ
    Posts
    23,710
    Blog Entries
    1

    Default Re: Run an shell script via a udev rule

    For instance, if i used this shell script to launch an instance of firefox or leafpad, the application is launched if I run the script from terminal.
    But nothing happens when I try to call the shell script from my "autodvd" script.
    It would be more useful if you showed us your actual /home/jean/some-script.sh script ie what is it you're trying to do. If you're really trying to launch a graphical program within a user's X-session from outside that session (via udev for example), the display environment and xauthrority become important considerations

    A recent thread on related topic
    https://forums.opensuse.org/showthre...l-app-via-cron

  4. #4
    Join Date
    Sep 2012
    Posts
    7,106

    Default Re: Run an shell script via a udev rule

    Quote Originally Posted by deano_ferrari View Post
    If you're really trying to launch a graphical program within a user's X-session from outside that session (via udev for example), the display environment and xauthrority become important considerations
    Any program launched by udev rule will be killed after very short time. udev by design does not allow long-running processes to remain.

  5. #5
    Join Date
    Jun 2008
    Location
    Auckland, NZ
    Posts
    23,710
    Blog Entries
    1

    Default Re: Run an shell script via a udev rule

    Quote Originally Posted by arvidjaar View Post
    Any program launched by udev rule will be killed after very short time. udev by design does not allow long-running processes to remain.
    Yep, true. We need to know what the OP is trying to accomplish

  6. #6
    Join Date
    Jun 2008
    Location
    Auckland, NZ
    Posts
    23,710
    Blog Entries
    1

    Default Re: Run an shell script via a udev rule

    I am using OpenSUSE Leap 42.3 on my laptop, and am working on a program that will detect when a CD/DVD drive is inserted or removed.
    @taronyu: There is a nice approach described in this blog which uses a custom systemd user service which is started when a CDROM/DVD is present. This might be more appropriate for your need, (otherwise please provide more info about what you're trying to accomplish).

    I tested by creating a minimal service (~/.config/systemd/user/dvd.service) with
    Code:
    [Unit]
    Description=Automatically start application when optical media inserted
    After=dev-dvd.device
    Requisite=dev-dvd.device
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/firefox
    StandardOutput=journal
    
    [Install]
    WantedBy=dev-dvd.device
    I enabled (as user) with
    Code:
    systemctl --user enable firefox.service
    *dev-cdrom.device and dev-cdrom.device both seem to work equally well. I only tested with a DVD ISO I had at hand, and firefox was just a means to test that the service file was started upon insertion.
    Last edited by deano_ferrari; 10-Feb-2018 at 02:58.

  7. #7
    Join Date
    Sep 2012
    Posts
    7,106

    Default Re: Run an shell script via a udev rule

    I do not see how this service can possibly work. /dev/dvd existence does not depend on media presence. Can you show "systemctl --user status dev-dvd.device" before and after medium is inserted?

  8. #8

    Post Re: Run an shell script via a udev rule

    Hi and thanks to all of you for your answers !

    So I can't do anything that needs access to X, as it is executed in a text-only bash, and that might compute a while as it will be kicked...
    This is interesting and obviously what I was doing does not work.

    So yes, it seems that I need to explain a little more.

    What I was trying to do in my SH script :
    I was launching Firefox, asking it to open a specific local HTML page, to test if the whole process (udev rule -> bash script in /usr/local/bin/ -> .sh script in /home/jean/) was fine.
    Something like this :
    Code:
    firefox "/home/jean/disc-inserted.html"
    or
    Code:
    firefox "/home/jean/disc-ejected.html"
    So, now I understand that firefox will not spawn as it needs an access to the graphical server.
    And even if it achieved to launch, it would be kicked soon.
    I'm quite new to all this system stuff but I will remember these two points !

    I could easily replace this by a non-graphical, fast command that could allow me to ensure the whole process is working.
    For instance, I might simply write "INSERTED" or "EJECTED" to another log file, from this .sh script... Doing this should be right, I think ?

    But this is just for testing, what I need to do after will require to execute some commands and run a binary.
    Time to explain this aspect of the project !

    What I will need to do :
    I want to be able to know when a disc in ejected and inserted in the drive. Then, if inserted, I have to run some commands that will mount the disc to a specific folder for later use, and finally run an application. This application will most probably be a custom program built from C++ and that uses sockets to inform another - and bigger - application that a disc has been inserted and mounted in a folder.
    Why ?

    I'm working with a friend on a personal project that aims to make a very little game machine from a Raspberry Pi 3.
    We work on all the aspects of the project : installing and configuring the OS, configuring a develoment environment, development of a 2D game engine, and finally making some games.

    I want to be able to detect disc insertion, auto-mount it in a folder, and then, once the bigger application has checked if it is a game disc, install/launch the game.

    So, maybe my approach is bad ? The service one looks intersting, if I can get it working I will give it a try !
    I'm open to any suggestion for this topic !

    Thanks a lot

  9. #9
    Join Date
    Jun 2008
    Location
    San Diego, Ca, USA
    Posts
    13,295
    Blog Entries
    2

    Default Re: Run an shell script via a udev rule

    A general FYI...
    If you can describe what you want your script to do sufficiently well,
    I've found that searching the gists at github usually turns up something useful.

    TSU
    Beginner Wiki Quickstart - https://en.opensuse.org/User:Tsu2/Quickstart_Wiki
    Solved a problem recently? Create a wiki page for future personal reference!
    Learn something new?
    Attended a computing event?
    Post and Share!

  10. #10
    Join Date
    Jun 2008
    Location
    Auckland, NZ
    Posts
    23,710
    Blog Entries
    1

    Default Re: Run an shell script via a udev rule

    Quote Originally Posted by arvidjaar View Post
    I do not see how this service can possibly work. /dev/dvd existence does not depend on media presence. Can you show "systemctl --user status dev-dvd.device" before and after medium is inserted?
    It works because device units are reloaded by systemd whenever the corresponding device generates a 'changed' event. It has nothing to do with the presence of /dev/dvd directly - systemd abstracts these device nodes as .device units anyway.

    From boot, and prior to media insertion...
    Code:
    ~> systemctl --user status  dvd.service
    ● dvd.service - Automatically start application when optical media inserted
       Loaded: loaded (/home/dean/.config/systemd/user/dvd.service; enabled; vendor preset: enabled)
       Active: inactive (dead)
    
    Feb 11 10:22:11 linux-54cw systemd[1776]: Stopped Automatically start application when optical media inserted.
    Upon disk insertion...
    Code:
    dean@linux-54cw:~> systemctl --user status  dvd.service
    ● dvd.service - Automatically start application when optical media inserted
       Loaded: loaded (/home/dean/.config/systemd/user/dvd.service; enabled; vendor preset: enabled)
       Active: inactive (dead) since Sun 2018-02-11 10:27:46 NZDT; 12s ago
      Process: 2512 ExecStart=/usr/bin/firefox (code=exited, status=0/SUCCESS)
     Main PID: 2512 (code=exited, status=0/SUCCESS)
    
    Feb 11 10:27:46 linux-54cw systemd[1776]: Starting Automatically start application when optical media inserted...
    Feb 11 10:27:46 linux-54cw systemd[1776]: Started Automatically start application when optical media inserted.
    dean@linux-54cw:~>
    If I remove media and insert another, I get another event generated, and the service file is triggered again.
    Last edited by deano_ferrari; 10-Feb-2018 at 16:38.

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •