4

I have made a script to run rsync, and added read line at the end to keep the output visible after it has run; this works as intended when I run the script manually.

I have made a udev rule RUN+="/home/user/bin/scriptfile" to run my above script and the script does run as intended, but output is not displayed in a terminal window. Why not, and how can I make it so?

edit - to clarify: I have tried initiating various different scripts from udev rules, and it works fine, scripts run and do what I expect them to. The question is, can I have the output printed to my screen when a script runs. I can direct the output to a log file, that works too, but I'd like to get it visible on the screen when the script is being run.

6
  • Check /var/log/syslog for terminal output of background jobs. Apr 3, 2017 at 19:48
  • 'var/log/syslog' does not contain output of the script.
    – kurja
    Apr 3, 2017 at 19:54
  • 2
    Scripts by default output only to stdout stream, so unless you explicitly launch a terminal window from within the script, you won't see one. Additionally, udev scripts don't inherit all the same environment variables, which means they have no way of knowing where and which GUI session you are running. Apr 3, 2017 at 21:13
  • 1
    your script is probably getting killed, too. if your read line is operating properly and waiting for input (that will never arrive...), it'll hit udev's time limit and be terminated. processes launched by udev in this way need to return quickly so they don't block other udev actions.
    – quixotic
    Apr 3, 2017 at 21:36
  • You can try adding the logger command to your script which is used to send messages to /var/log/syslog also you should post your script in your question in hopes others can spot coding errors. Also post contents of UDEV rule, its file name, file properties and directory stored in, etc. The more information the better. Apr 3, 2017 at 21:46

1 Answer 1

5
+50

First of all why don't you see output? As pointed out by Sergiy Kolodyazhnyy in the comments, scripts started by udev "don't inherit all the same environment variables, which means they have no way of knowing where and which GUI session you are running." In simpler terms, udev is ignorant when it comes to your desktop GUI.

I currently do something similar to what you've asked for USB devices that are plugged into my system. For an application I'm running, I need to know if the USB has a valid serial number. Anyway, here's how I made it happen.

Overview:

  • I start a helper script that creates a named pipe and watches that named pipe for "messages" traveling across it.
  • I have udev configured to "send messages" (write lines) to my named pipe (in my case USB sn and partition info).
  • My helper script sees each line of text come in and I use notify-send to dump the message on my screen in the form of a notification.

If you just want to see it in a terminal window, you could tell your helper script to simply echo text from the named pipe in the terminal window.


Sample code:

#!/bin/bash
#This script should be called once without an argument to get it running in a "service" mode
#Successive calls to this script by UDEV sould pass a string as the first argument.
#   These strings will then be displayed in the window running in service mode.

pipe=/tmp/messages

if [ "$1" == "" ]; then

    [ ! -e  "$pipe" ] && mkfifo "$pipe"

    while true # this loop continuously reads new lines and echos them
    do
        line=$(cat "$pipe")
        echo "$line"
    done
fi

# you won't reach this line unless you call this script with one argument
echo "$1" >> "$pipe"

Running this script:

  • Save the above in a file /tmp/sample_script.sh (will be deleted on reboot)
  • Make the script executable chmod +x /tmp/sample_script.sh
  • Call the script to get it running in service mode (ie. without any arguments) /tmp/sample_script.sh
  • From another terminal window/script/udev, run /tmp/sample_script.sh "message to send" (notice we're passing the string argument, "message to send", here)
  • Look back at the service window, and you'll see that the string, "message to send", has appeared in the window.

When running the script from udev, you won't be able to get the second instance to output anything on the screen directly without redirecting it through the named pipe because your udev script is called from an environment that is completely separate from the environment your GUI is running in. The named pipe created in the script and utilized in both environments acts like a bridge between the two, allowing you to pass information from the udev environment to the GUI environment you're looking at.

1
  • Could you please elaborate on how to "tell your helper script to simply echo text from the named pipe in the terminal window"?
    – kurja
    Apr 20, 2017 at 18:56

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.