我很难精确地表达问题,但我会尽力而为。我使用dwm
默认的窗口管理器dmenu
作为我的应用程序启动器。除了浏览器外,我几乎不使用GUI应用程序。我的大部分工作都是直接从命令行完成的。此外,我非常热衷于有关操作系统,应用程序等的极简主义。我从未遗弃的工具之一是应用程序启动器。主要是因为我对应用程序启动器的工作方式/工作方式缺乏确切的了解。即使是广泛的互联网搜索也只能显示模糊的解释。我想做的就是摆脱我的应用程序启动器,因为除了实际生成应用程序之外,我对此完全没有用。为了做到这一点,我真的很想知道如何从外壳“正确”启动应用程序。因此,“正确”的含义可以近似为“像应用程序启动程序那样”。
我知道以下几种从shell生成进程的方法:
exec /path/to/Program
用指定的命令替换shell而不创建新进程sh -c /path/to/Program
启动依赖于外壳的进程/path/to/Program
启动依赖于外壳的进程/path/to/Program 2>&1 &
启动外壳独立进程nohup /path/to/Program &
启动独立于Shell的进程并将输出重定向到nohup.out
更新1:我可以举例说明在不同条件下dmenu
从重复调用到重新构造它的方法ps -efl
。它产生一个新的shell,/bin/bash
并作为该shell的子级应用程序/path/to/Program
。只要孩子在身边,壳就会在附近。(如何管理它超出了我的范围...)相反,如果您nohup /path/to/Program &
从shell 发出,/bin/bash
则该程序将成为该shell的子级,但如果退出该shell,则该程序的父级将是最高级的进程。因此,如果第一个进程例如是/sbin/init verbose
并且已经存在,PPID 1
那么它将成为程序的父级。这里就是我试图用一个图表来解释:chromium
推出通过dmenu
,firefox
使用推出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
更新2:我想这个问题也可以归结为:流程的父级应该是什么?例如,它应该是一个外壳,还是应该是一个init
过程,即具有的过程PID 1
?
init
-答案可能是...也许?这取决于您打算如何/是否与之交谈,init
您使用什么以及数据通道在哪里。通常,这些东西会自行解决-这就是要这样做的init
原因。在任何情况下,通常当您守护进程then时init
。或者,如果要作业控制,请使用当前的shell。
dmenu
并查看如何与所学内容相处。我发现exec /path/to/Program & exit
或/bin/bash -c /path/to/Program & exit
相当有用。但是,他们都作出1
即init
在母公司Program
这是我没意见,只要这是有道理的,并没有违反任何基本*nix
原则。
systemd--bash--chromium
。systemd--chromium
当我从外壳中生成Firefox时,我尝试的所有方法最终都将导致以下形式的进程树。贝壳在这里如何被妖魔化?它与任何终端都没有关联。