3

I'm trying to bring up a terminal to interactively ask for a file, and open it using a GUI program:

foot /bin/sh -c 'file=`fzf`;(setsid xdg-open "$file" &)'

I'm using setsid, because otherwise the terminal takes down the xdg-open with it when it exits. The command above, however, doesn't work: it still exits without showing anything on the screen. However, when I add a sleep at the end, it does work:

foot /bin/sh -c 'file=`fzf`;(setsid xdg-open "$file" &); sleep 0.0000000001'

The terminal exits, but the process started by xdg-open remains running.

What is going on here? Is there a cleaner way such that I can avoid the sleep (because I assume the exact time to sleep depends on the system).

I tried using disown, but this doesn't work at all (even with the sleep).

Remko
  • 133
  • 1
    It seems that without sleep the terminal sh gets a HUP signal before setsid gets spawned. This can happen, because you background it. Your sleep makes sure that the parent session calling setsid is around for just the tiny amount of time to get setsid do its thing. – jpe Oct 14 '22 at 20:47

1 Answers1

3

The background process:

  1. detaches from the terminal (setsid);
  2. runs xdg-open.

If the terminal disappears before step 1 is finished, the whole process group receives a SIGHUP and is killed. setsid prevents the SIGHUP from reaching xdg-open, but that doesn't help if setsid (or the subshell working to invoke setsid) is killed before setsid has done its job.

The fix is to detach from SIGHUP in the foreground.

foot /bin/sh -c 'file=`fzf`; setsid sh -c "xdg-open \"\$1\" &" sh "$file"'

Another solution would be to ignore SIGHUP.

foot /bin/sh -c 'file=`fzf`; trap "" SIGHUP; xdg-open "$file" &'