I find it hard to phrase the question precisely but I will give my best. I use dwm
as my default window manager and dmenu
as my application launcher. I hardly use GUI applications aside from my browser. Most of my work is done directly from the command line. Furthermore, I'm a great fan of minimalism regarding operating systems, applications etc. One of the tools I never got rid of was an application launcher. Mainly because I lack a precise understanding of how application launchers work/what they do. Even extensive internet search only shows up vague explanation. What I want to do is get rid even of my application launcher because apart from actually spawning the application I have absolutely no use for it. In order to do this I would really like to know how to "correctly" start applications from the shell. Whereby the meaning of "correctly" can be approximated by "like an application launcher would do". I do not claim that all application launchers work the same way because I do not understand them well enough.
I know about the following ways to spawn processes from the shell:
exec /path/to/Program
replace shell with the specified command without creating a new processsh -c /path/to/Program
launch shell dependent process/path/to/Program
launch shell dependent process/path/to/Program 2>&1 &
launch shell independent processnohup /path/to/Program &
launch shell independent process and redirect output tonohup.out
Update 1: I can illustrate what e.g. dmenu
does reconstructing it from repeated calls to ps -efl
under different conditions. It spawns a new shell /bin/bash
and as a child of this shell the application /path/to/Program
. As long as the child is around so long will the shell be around. (How it manages this is beyond me...) In contrast if you issue nohup /path/to/Program &
from a shell /bin/bash
then the program will become the child of this shell BUT if you exit this shell the program's parent will be the uppermost process. So if the first process was e.g. /sbin/init verbose
and it has PPID 1
then it will be the parent of the program. Here's what I tried to explain using a graph: chromium
was launched via dmenu
, firefox
was launched using exec firefox & exit
:
systemd-+-acpid
|-bash---chromium-+-chrome-sandbox---chromium-+-chrome-sandbox---nacl_helper
| | `-chromium---5*[chromium-+-{Chrome_ChildIOT}]
| | |-{Compositor}]
| | |-{HTMLParserThrea}]
| | |-{OptimizingCompi}]
| | `-3*[{v8:SweeperThrea}]]
| |-chromium
| |-chromium-+-chromium
| | |-{Chrome_ChildIOT}
| | `-{Watchdog}
| |-{AudioThread}
| |-3*[{BrowserBlocking}]
| |-{BrowserWatchdog}
| |-5*[{CachePoolWorker}]
| |-{Chrome_CacheThr}
| |-{Chrome_DBThread}
| |-{Chrome_FileThre}
| |-{Chrome_FileUser}
| |-{Chrome_HistoryT}
| |-{Chrome_IOThread}
| |-{Chrome_ProcessL}
| |-{Chrome_SafeBrow}
| |-{CrShutdownDetec}
| |-{IndexedDB}
| |-{LevelDBEnv}
| |-{NSS SSL ThreadW}
| |-{NetworkChangeNo}
| |-2*[{Proxy resolver}]
| |-{WorkerPool/1201}
| |-{WorkerPool/2059}
| |-{WorkerPool/2579}
| |-{WorkerPool/2590}
| |-{WorkerPool/2592}
| |-{WorkerPool/2608}
| |-{WorkerPool/2973}
| |-{WorkerPool/2974}
| |-{chromium}
| |-{extension_crash}
| |-{gpu-process_cra}
| |-{handle-watcher-}
| |-{inotify_reader}
| |-{ppapi_crash_upl}
| `-{renderer_crash_}
|-2*[dbus-daemon]
|-dbus-launch
|-dhcpcd
|-firefox-+-4*[{Analysis Helper}]
| |-{Cache I/O}
| |-{Cache2 I/O}
| |-{Cert Verify}
| |-3*[{DOM Worker}]
| |-{Gecko_IOThread}
| |-{HTML5 Parser}
| |-{Hang Monitor}
| |-{Image Scaler}
| |-{JS GC Helper}
| |-{JS Watchdog}
| |-{Proxy R~olution}
| |-{Socket Thread}
| |-{Timer}
| |-{URL Classifier}
| |-{gmain}
| |-{localStorage DB}
| |-{mozStorage #1}
| |-{mozStorage #2}
| |-{mozStorage #3}
| |-{mozStorage #4}
| `-{mozStorage #5}
|-gpg-agent
|-login---bash---startx---xinit-+-Xorg.bin-+-xf86-video-inte
| | `-{Xorg.bin}
| `-dwm-+-dwmstatus
| `-xterm---bash-+-bash
| `-pstree
|-systemd---(sd-pam)
|-systemd-journal
|-systemd-logind
|-systemd-udevd
|-wpa_actiond
`-wpa_supplicant
Update 2: I guess the question can also be boiled down to: What should be the parent of a process? Should it e.g. be a shell or should it be the init
process i.e. the process with PID 1
?
init
- to which the answer might be... maybe? it depends on how/if you plan to talk to it, whatinit
you use, and where the data channels are. In general that stuff will tend to work itself out - that's whatinit
is for. In any case, usually when you daemonize a process theninit
. Or if you want job control, current shell.dmenu
and see how I get along with what I learned. I findexec /path/to/Program & exit
or/bin/bash -c /path/to/Program & exit
to be quite usable. But they all make1
i.e.init
the parent of theProgram
which is fine with me as long as this makes sense and does not violate any basic*nix
principles.exec &
, I think. I usually just do my stuff from the terminal... maybe you'd get some use out of ben crowell's question here. I have an answer there, but all of them are very good. anyway, when you background a process and its parent dies like:sh -c 'cat & kill $$'
you orphan it, and it winds up getting reaped eventually. that's init's job - that's why they all fall to it.systemd--bash--chromium
. All methods I try will ultimately lead to a process tree of the following formsystemd--chromium
when I spawn firefox from the shell. How is the shell demonized here? It is not associated with any terminal.