シェルでアプリケーションを「正しく」起動する方法

シェルでアプリケーションを「正しく」起動する方法

この質問を正確に表現するのは難しいですが、頑張ります。私はそれをdwmメインウィンドウマネージャとdmenuアプリケーションランチャーとして使用します。私はブラウザ以外のGUIアプリケーションをほとんど使用しません。私の仕事のほとんどはコマンドラインから直接行われます。また、私はオペレーティングシステム、アプリなどでミニマリズムが好きです。私が決してアンインストールしないツールの1つはアプリランチャーです。これは、主にアプリランチャーがどのように機能するか、何をするのかを正確に理解できないためです。インターネットを一生懸命検索してもあいまいな説明しか出ません。私がやりたいことは、実際にアプリを作成する以外にはまったく役に立たないので、アプリランチャーを取り除くことです。そのために、シェルでアプリケーションを「正しく」実行する方法を知りたいです。 「正しい」の意味は、「アプリケーション実行プログラムが行うように」として近似することができます。私はアプリランチャーについて十分に知らないので、すべてのアプリランチャーが同じように動作すると主張するわけではありません。

私はシェルからプロセスを作成する次の方法を知っています。

  1. exec /path/to/Program新しいプロセスを作成せずにシェルを指定したコマンドに置き換える
  2. sh -c /path/to/Programシェル関連プロセスの開始
  3. /path/to/Programシェル関連プロセスの開始
  4. /path/to/Program 2>&1 &シェル独立プロセスの開始
  5. nohup /path/to/Program &シェルスタンドアロンプ​​ロセスを開始し、出力を次にリダイレクトします。nohup.out

更新1:他の条件でdmenu繰り返し呼び出しを介して再生成するなどの操作を説明できます。ps -eflこれは新しいシェルを作成し、/bin/bashそのシェルのサブアプリケーションとして機能します/path/to/Program。子供が周りにいる限り、殻は常に周りにあります。 (これを管理する方法は私の能力ではありません...)代わりに、シェルでnohup /path/to/Program &実行すると/bin/bashプログラムはそのシェルの子プロセスになりますが、そのシェルを終了するとプログラムの親プロセスは最上位プロセスになります。したがって、最初のプロセスが/sbin/init verboseすでに存在する場合は、PPID 1そのプログラムの親プロセスになります。ダイアグラムを使用して説明する内容は次のとおりです。chromiumはじめにdmenufirefoxはじめに使用する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

ベストアンサー1

プログラムを実行して端末から切り離す方法はいくつかあります。一つは、バックグラウンドで実行することです。サブシェル、次のように(firefoxお気に入りのプログラムに置き換えます):

(firefox &)

もう一つは、プロセスを拒否することです。

firefox & disown firefox

アプリケーションランチャーのしくみがわからない場合は、dmenuバイナリ1つとシェルスクリプト2つ(dmenu、、、dmenu_path)を提供してくださいdmenu_run

dmenu_runの出力をdmenu_pathdmenuにパイプすると、$SHELL設定した変数にパイプされます。空の場合は使用されます/bin/sh

#!/bin/sh
dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &

dmenu_path少し複雑ですが、簡単に言えば、$PATH環境変数にバイナリリストを提供し、可能であればキャッシュを使用します。

#!/bin/sh
cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"}
if [ -d "$cachedir" ]; then
        cache=$cachedir/dmenu_run
else
        cache=$HOME/.dmenu_cache # if no xdg dir, fall back to dotfile in ~
fi
IFS=:
if stest -dqr -n "$cache" $PATH; then
        stest -flx $PATH | sort -u | tee "$cache"
else
        cat "$cache"
fi

プログラムをシェルで実行する必要はありません。シェルに接続せずに作成する別の方法は次のdmenu_runとおりです。

#!/bin/sh
$(dmenu_path | dmenu "$@") &

おすすめ記事