A bit of context: I am creating a small Python programming lab for novice users. I want them to use Python's IDLE editor (which you launch as python -m idlelib) but since they may not be comfortable using the terminal, I wanted them so have something they can click on in nautilus (Gnome's file manager) that will launch IDLE. More precisely I want to launch IDLE using a Python virtual environment, so the command becomes .venv/bin/python -m idlelib
So here is the file I created, named idle and marked as executable (chmod u+x):
#!/usr/bin/env bash .venv/bin/python -m idlelib If you double-click on it and select “run”, you get IDLE, all is well. However when you double-click on it you get several buttons, one is “run” but another one is “run in terminal”. I would like to make sure that users have the same experience whatever button they click.
With the above script, if you chose “run in terminal” you have both IDLE and a terminal that pop up. This may be confusing for users, especially since closing the terminal will kill IDLE. Adding & after the command closes the terminal, but then IDLE gets closed as well because its “parent” (the terminal) was terminated.
So I heard about nohup and setsid that seem to be what I need, but something strange happens. Here is a script that does (more or less) what I want:
#!/usr/bin/env bash setsid .venv/bin/python -m idlelib & sleep 1 When you click on this script and select “run in terminal”, a terminal appears, then IDLE appears, then the terminal goes away but IDLE stays.
Notice the sleep 1 at the end, though: if you remove it, the terminal appears only for a fraction of a second and IDLE never shows up. This happens both with setsid and nohup.
My question is: why is this sleep 1 necessary?
My guess would be that IDLE takes some time to start and that it is not able to “survive” the closing of the terminal until it is fully up. But it's weird, I would expect a program launched with setsid to be instantly independant from the process that launched it.
nohuporsetsid, with(trap '' HUP; your_python_command </dev/null >/dev/null 2>&1 &)(And no, you never need that#! /usr/bin/env bashcargo-cult talisman either -- simply#! /bin/shwill do, andsetsidis not intended to be used with&).