2

I'm using Ubuntu 20.04 and I'm looking for a bash script to start Quodlibet (a music application) and conky simultaneously. Edit: The idea is to use the sh script in a .desktop launcher

  1. Start Quodlibet
  2. Start conky 2 seconds later
  3. Close conky if Quodlibet is closed

I made some tests but I believe the following script won't work because I doesn't catch the closing of Quodlibet. Conky is still running when I close Quodlibet.

#!/bin/bash
trap "exit" INT TERM ERR
trap "kill 0" EXIT

quodlibet & sleep 2 && conky &

wait

EDIT: Standalone .sh solution

Working script, thanks to @berndbausch.

#!/bin/bash
quodlibet & QUODPID=$!
sleep 3 &&
conky & CONKYPID=$!

wait $QUODPID kill $CONKYPID

EDIT: Using a custom launcher

As explained by @xhienne in his answer, using exec=setsid /path/to/script.sh in the .desktop file as well as his script works well.

BFlat
  • 123
  • 2
    Store Quodlibet's PID right after starting it QUODPID=$!, then, after starting conky, store its PID as well. Wait for Quodlibet's termination with wait $QUODPID. Then kill conky. – berndbausch Apr 21 '21 at 13:45
  • 1
    I want to create a .sh file that I will execute with a custom launcher (.desktop). – BFlat Apr 21 '21 at 13:57
  • @berndbausch I edited my question but I can't figure it out, conky is not killed. – BFlat Apr 21 '21 at 14:13
  • 2
    The ampersand behind CONKYPID=$! puts the assignment into a subshell, so that the CONKYPID in the main program is not affected. Remove the ampersand and it should work. Same for the QUODPID, by the way. – berndbausch Apr 21 '21 at 14:26
  • Thanks @berndbausch, it works great ! – BFlat Apr 21 '21 at 14:50
  • This solution is working great when I only run the script inside a terminal. But when I create a launcher, it open quodlibet and conky as planned, but it never closes conky when I exit quodlibet. – BFlat Apr 21 '21 at 16:47

1 Answers1

4

Just start Quodlibet in the current shell, not in a sub-process:

#!/bin/bash
trap "exit" INT TERM ERR
trap "kill 0" EXIT

(sleep 2 && conky) &

quodlibet

[update] You mention that you want to run this script from a .desktop file in a graphical environment. @fra-san made me aware that every process run this way are likely to inherit their parent's process group and that, as a consequence, kill 0 will kill that launcher process and (potentially) all the processes it has started. This is certainly not what you want.

The solution to this is to start your script with setsid so as to create a new process group dedicated to it:

setsid /path/to/script.sh
fra-san
  • 10,205
  • 2
  • 22
  • 43
xhienne
  • 17,793
  • 2
  • 53
  • 69
  • The intention of putting the script in a .desktop file didn't make it to the question's body, but it makes kill 0 quite dangerous because programs invoked by means of .desktop files share their process group with the process that started them (at least in some desktop environments, I could check with KDE). – fra-san Apr 21 '21 at 14:48
  • I didn't know putting the script in a .desktop file would change anything, I'll edit my question so that it appears. – BFlat Apr 21 '21 at 14:52
  • As I said, I can only check on KDE, where I confirm that a script Executed from a .desktop file, when started by means of the launcher widget (krunner), belongs to the same process group of the launcher widget itself (also shared by all other applications that don't take care of changing their own process group). Same thing happens if the .desktop file is double-clicked in a file manager. By default, child processes share the same group of their parent. – fra-san Apr 21 '21 at 15:33
  • This solution works well using a custom launcher. It closes conky as expected but there's a weird thing happening just after, it's like my session is closed and restart – BFlat Apr 21 '21 at 16:52
  • It closes conky using setsid that's great ! – BFlat Apr 21 '21 at 17:09
  • 1
    @xhienne (re to a previous comment of yours) a terminal emulator started from a .desktop file may have the same pgrp of its parent process (e.g. Konsole, the one I'm using, does), but each pseudo-terminal it creates needs its own session leader, hence its own session and its own process group. Combining this with job control, by default enabled in interactive shells, and the fact that they ignore INT/QUIT/TERM, there's usually no way a kill 0 could terminate the terminal emulator or its ancestors... – fra-san Apr 21 '21 at 19:07
  • ... (Sorry for all this noise, I'll happily remove all my comments -- more happily if you added a notice about setsid/process groups to your answer). – fra-san Apr 21 '21 at 19:07
  • @fra-san Hmmm, your "noise" is very welcome actually. I have updated my answer but you can leave your comments here, they are helpful (more than mine that I'm deleting right now). Thank you! – xhienne Apr 21 '21 at 19:26