4

How would a bash script know if it has been launched by a .desktop file, and how would it know the path of that launcher?

Extra Points: How would I extract the "comment" field of that .desktop file - to be used within the script?

  • 1
    Maybe call that script with a parameter? – Alex Tartan Aug 8 '15 at 10:34
  • @AlexTartan That's currently what i'm doing, is running the script with a parameter, and it's workable. But, It would make my workflow a tad simpler if the script would act differently based on the filename of the launcher file. – Richard LeClair Aug 8 '15 at 10:41
5

The environment variable GIO_LAUNCHED_DESKTOP_FILE contains the path to the .desktop file, and GIO_LAUNCHED_DESKTOP_FILE_PID contains the process ID of the program originally invoked by the .desktop file. You need to check the PID, otherwise you might incorrectly believe the script to have been invoked by a desktop file, whereas it was actually invoked by a program invoked by a program invoked by a program invoked by the desktop file.

if [ -n "$GIO_LAUNCHED_DESKTOP_FILE" ] && [ "$$" -eq "$GIO_LAUNCHED_DESKTOP_FILE_PID" ]; then
  echo "I was invoked by $GIO_LAUNCHED_DESKTOP_FILE"
else
  echo "I wasn't invoked by a .desktop file"
fi

This may not work in all applications or in all environments, because this environment variable didn't exist back when .desktop files were introduced, it might not be supported everywhere yet. Gnome applications should all work since the job is done in the Glib library.

Note that if the desktop file has Terminal=true, the environment variable may not end up being set, if the terminal emulator has a single process that runs all instances rather than one process per instance. That's how Gnome-terminal works, for example. The same applies if you explicitly run gnome-terminal … as the command in the desktop file. Terminal emulators that run one process per terminal, such as xterm, will work fine.

I'm not aware of any shell tool to parse desktop files. You can use ordinary tools such as grep, sed, awk and so on, but you'll have to handle things like backslash escapes and per-language entries (or choose not to support them). Here's a script that extracts the comment in the simple case (no backslashes, default language).

if [ -n "$GIO_LAUNCHED_DESKTOP_FILE" ] && [ "$$" -eq "$GIO_LAUNCHED_DESKTOP_FILE_PID" ]; then
  comment=$(<"$GIO_LAUNCHED_DESKTOP_FILE" sed -n 's/^Comment=//p')
  if [ -n "$comment" ]; then
    echo "I was invoked by $GIO_LAUNCHED_DESKTOP_FILE with the following comment:"
    echo "$comment"
  else
    echo "I was invoked by $GIO_LAUNCHED_DESKTOP_FILE with no comment"
  fi
else
  echo "I wasn't invoked by a .desktop file"
fi
  • it seems neither the $GIO_LAUNCHED_DESKTOP_FILE nor the $GIO_LAUNCHED_DESKTOP_FILE_PID variables are being set. My .desktop file does contain Terminal=true so my script will accomplish my goal which is to prompt me for text (using the only command I know to accomplish this, the read -p command) that is then appended to a text file. Is this a catch 22? Is there another way to prompt for text? – Richard LeClair Aug 9 '15 at 3:43
  • @RichardLeClair If you want to have the environment variables, you need to use a terminal emulator that runs one process per instance (or that arranges to transmit environment variables from the launcher stub to the terminal instance). Otherwise the program is not launched from the launcher, it's launched from the running terminal emulator process (e.g. the gnome-terminal process) which receives a message from the launcher that only tells it what command to run and not what launcher it came from. – Gilles 'SO- stop being evil' Aug 9 '15 at 10:25

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.