私はUbuntu上でTilda(ドロップダウンターミナル)を私の “コマンドセンター “として使用しています – 他の人がGNOME Do、QuicksilverやLaunchyを使用するかもしれないほとんどの方法
しかし、私はどのようにしてプロセス(例えば Firefox)を起動した端末から完全に切り離すか、つまり、そのような(非)子プロセスを防ぐかで苦労しています
- は、発信元端末を閉じると終了します
- 送信元端末をSTDOUT/STDERR経由で “汚染 “する
例えば、「ちゃんとした」ターミナルウィンドウでVimを起動するために、以下のような簡単なスクリプトを試してみました
exec gnome-terminal -e "vim $@" &> /dev/null &
しかし、それではやはり汚染の原因になります(また、ファイル名を渡すとうまくいかないようです)
333 None 2009-03-23
まず第一に、一度プロセスを開始したら、それをバックグラウンドにするには、まずプロセスを停止させ(Ctrl–Zを打つ)、次にbg
と入力してバックグラウンドで再開させることができます。これで「ジョブ」となり、stdout
/stderr
/stdin
はまだターミナルに接続されています
プロセスの最後に”& “をつけることで、すぐにバックグラウンドとして処理を開始することができます
firefox &
バックグラウンドで無音で実行するには、これを使用します
firefox </dev/null &>/dev/null &
いくつかの追加情報
nohup
は、標準出力/標準出力をファイルに送ることができ、親スクリプトを閉じても子スクリプトを SIGHUP しないように、アプリケーションを実行するためのプログラムです。しかし、アプリケーションを起動する前にこれを使用する先見の明が必要です。nohup
の仕組み上、実行中のプロセスに適用することはできません
disown
はシェルのジョブリストからシェルのジョブを削除する bash ビルトインです。これは基本的に何を意味するかというと、fg
, bg
が使えなくなるということですが、より重要なことは、シェルを閉じたときにハングしたり、その子にSIGHUP
を送ったりしなくなるということです。nohup
とは異なり、disown
はプロセスが起動してバックグラウンド化された後に使用されます
できないことは、プロセスを起動した後にプロセスの標準出力/標準出力/標準出力/標準出力/標準出力を変更することです。少なくともシェルからはできません。プロセスを起動して、その標準出力があなたのターミナルであることを伝えた場合 (デフォルトではそれが行われています)、そのプロセスはあなたのターミナルに出力するように設定されています。シェルはプロセスの FD 設定とは何の関係もありません。プロセス自身は標準出力/stderr/stdinを閉じるかどうかを決めることができますが、シェルを使って強制的にそうさせることはできません
バックグラウンドプロセスの出力を管理するために、スクリプトから多くのオプションがあります。しかし、起動したものの消音するのを忘れてしまった対話型プロセス (firefox < /dev/null &>/dev/null &
) では、あまり何もできません
GNU screen
を入手することをお勧めします。スクリーンを使えば、プロセスの出力が面倒になったときに実行中のシェルを閉じて新しいシェルを開くことができます (^Ac
)
あ、ちなみに「$@
」を使っているところで「$@
」を使うのはやめましょう
$@
は、$1
, $2
, $3
…という意味で、コマンドはこれになります
gnome-terminal -e "vim $1" "$2" "$3" ...
e は引数を一つしか取らないので、これはおそらくあなたが望んでいるものではないでしょう。$1
を使って、スクリプトが一つの引数しか扱えないことを示してください
あなたが与えたシナリオ(gnome-terminal -e
で)で複数の引数を正しく動作させるのは本当に難しいです。引数を一つにエンコードしなければなりません。最良で最も堅牢な、しかしむしろ不器用な方法は、このようなものです
gnome-terminal -e "vim $(printf "%q " "$@")"
379 lhunath 2009-03-23
nohup cmd &
nohup
はプロセスを完全に切り離します(デーモン化)
209 dsm 2009-03-23
bash(1) を参照してください
もう一つの方法として、at now
を試してみてはいかがでしょうか。スーパーユーザでない場合は、at
の使用許可が制限されている可能性があります
66 Randy Proctor 2009-03-23
これらの回答を読んで、私は最初、nohup <command> &
を発行すれば十分だと思っていました。gnome-terminal で zsh を実行してみると、nohup <command> &
はシェルが終了時に子プロセスを殺すのを防げないことがわかりました。nohup
は特に非対話型のシェルでは便利ですが、SIGHUP
シグナルに対して子プロセスがハンドラをリセットしない場合にのみ、この動作が保証されます
私の場合、nohup
はハングアップシグナルがアプリケーションに到達するのを防ぐべきでしたが、子アプリケーション(この場合はVMWare Player)はSIGHUP
ハンドラをリセットしていました。その結果、ターミナルエミュレータが終了したときに、サブプロセスを殺すことができました。これは、私の知る限りでは、シェルのジョブテーブルからプロセスを削除することによってのみ解決できます。nohup
がシェルの組み込み関数でオーバーライドされている場合は、これで十分かもしれませんが、そうでない場合は
disown
は、bash
、zsh
、ksh93
に組み込まれたシェルです
<command> &
disown
or
<command> &; disown
を使用してください。これは、ジョブテーブルからサブプロセスを削除するという一般的に望ましい効果を持っています。これにより、誤って子プロセスにシグナルを送ることなくターミナルエミュレータを終了することができます。SIGHUP
ハンドラがどのように見えようとも、これは子プロセスを殺してはいけません
しかし、ターミナルエミュレータが終了した後、initプロセスに接続されているのを見ることができるはずです。言い換えれば、すべてが本来あるべき姿であり、おそらくあなたが望んでいる通りになっているということです
お使いのシェルが disown
をサポートしていない場合はどうすればいいのでしょうか?サポートしているシェルに切り替えることを強く推奨しますが、サポートしていない場合、いくつかの選択肢があります
screen
とtmux
はこの問題を解決することができますが、それらははるかに重いソリューションであり、私はそのような単純なタスクのためにそれらを実行しなければならないのが嫌いです。これらは、一般的にリモートマシン上で tty をメンテナンスしたい場合には、より適しています- 多くのユーザにとって、シェルが zsh の
setopt nohup
のような機能をサポートしているかどうかを確認することが望ましいかもしれません。これは、シェル終了時にジョブテーブルのジョブにSIGHUP
を送信しないように指定するために使うことができます。シェルを終了する直前にこれを適用するか、常にオンにしておきたい場合は~/.zshrc
のようにシェルの設定に追加してください - ジョブテーブルを編集する方法を探す。
tcsh
やcsh
では方法が見つからず、なんだか気になります - フォークオフと
exec()
を行う小さなC言語のプログラムを書く。これは非常に貧弱な解決策ですが、ソースは数十行で構成されているはずです。コマンドをコマンドライン引数としてCプログラムに渡すことができるので、ジョブテーブルのプロセス固有のエントリを避けることができます
44 Stephen Rosen 2014-01-22
nohup $COMMAND &
command & disownします
setsid command
私は2番をずっと使ってきましたが、3番でも十分に動作します。また、disown
はnohup
のフラグが-h
になっていて、-a
ですべてのプロセスをdisownでき、-ar
で実行中のすべてのプロセスをdisownできるようになっています
サイレンシングは$COMMAND &>/dev/null
によって達成される
これが役に立つことを願っています
33 Mr. Minty Fresh 2015-08-25
バッシュの最もシンプルで唯一の正解
command & disown
ターミナルからプロセスを切り離す必要はありませんが、シェルから切り離す必要はありません
10 ManuelSchneid3r 2017-05-05
スクリーンで解決できるかもしれませんね
9 None 2009-03-25
を使うと、プロセスを切り離すために括弧を使うことができます
Compare this:
> jobs # shows nothing
> firefox &
> jobs
[1] + Running firefox
To this:
> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>
これにより、ジョブリストから firefox が削除されますが、ターミナルにはまだ縛られています
9 Nathan Fellman 2009-03-23
ttyシェルを切り離すには、サブシェルからコマンドを実行してください
(command)&
終了時に使用していた端末が終了したが、プロセスが生きている場合
check –
(sleep 100) & exit
他の端末を開く
ps aux | grep sleep
プロセスはまだ生きている
8 jitendra 2012-08-07
ジョブのバックグラウンドとフォアグラウンドは、おそらくすべての Unix システム管理者が最初に知っておくべきことの一つでしょう
bashを使った方法をご紹介します
./script.sh
# suspend process
{ctrl-Z}
# background process
bg
# list all backgrounded jobs
jobs
# bring it back to foreground
fg
5 djangofan 2013-05-22
あなたはnohupコマンドを使用してコマンドを実行することができます、これはあなたのプロセスを切り離し、指定されたファイルに出力をリダイレクトします…しかし、私はそれが正確にあなたが必要とするものであるかどうかを確認していません
4 Ben 2009-03-23
これを bashrc/zshrc に追加するだけです
detach() {
"$@" 1>/dev/null 2>/dev/null &; disown
}
そうすると、このように勘当されたコマンドを実行することができます
detach gedit ~/.zshrc
3 B. Branchard 2018-02-05
daemonを試してみてください
2 Volker Stolz 2009-03-23
私の.bashrcには、まさにその目的のためにこれらの関数があります
function run_disowned() {
"$@" & disown
}
function dos() {
# run_disowned and silenced
run_disowned "$@" 1>/dev/null 2>/dev/null
}
コマンドの前にdos
を付けて、ターミナルから切り離して実行します
この関数は、bash
とzsh
で動作するように書かれています
1 mic_e 2015-06-14
kde-cli-tools パッケージで利用可能なKDEのkstart5
が役立ちます
kstart5 my-command &
guiを実行していれば、xウィンドウの複数のアスペクトを管理することも可能です
ソース。Linuxhacks.org ディスクロージャー: 私は Linuxhacks.org
の所有者です
1 intika 2020-05-02
Mac OS Xでは、ターミナルで子プロセスが引き裂かれないようにするには、nohup AND disownの両方を使う必要があることがわかりました
0 aaron 2010-06-19
私は以下のスクリプトを使っています。端末への印刷処理を停止し、nohup
でデタッチし、TIMEOUT
の範囲内でコマンドが終了するとリターンステータスで終了します
#!/bin/bash
TIMEOUT=0.1
CMD=( "$@" )
#Could have some shortcuts here, e.g. replace "somefile.c" with "gedit somefile.c"
#use nohup to run the command, suppressing its output and allowing the terminal to be closed
#also send nohup's output to /dev/null, supressing nohup.out
#run nohup in the background so this script doesn't block
#print the command for debugging and to see bash variable expansion
printf "%q " "${CMD[@]}"
echo
nohup "${CMD[@]}" >/dev/null 2>&1 &
NOHUP_PID=$!
#kill this script after a short time, exiting with success status - command is still running
#this is needed as there is no timeout argument for `wait` below
MY_PID=$$
trap "exit 0" SIGINT SIGTERM
sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally
#if the command finishes before the above timeout, everything may be just fine or there could have been an error
wait $NOHUP_PID
NOHUP_STATUS=$?
#print an error if there was any. most commonly, there was a typo in the command
[ $NOHUP_STATUS != 0 ] && echo "Error: $CMD"
#return the exit status of nohup, whatever it was
exit $NOHUP_STATUS
Usage example:
>>> run false
false
Error: false
>>> echo $?
1
>>> run true
true
>>> run sleep 10
sleep 10
>>>
0 jozxyqk 2014-09-21
sudo apt install ucommon-utils
pdetach command
これでいいですよ 🙂
0 d4rk4ng31 2019-06-21
現在の SSH セッションからプログラムを完全に切り離すには、run を実行します
setsid nohup script.sh &
そして、すべてのログ (stderr & stdout) をリダイレクトするには、以下のように実行します
setsid nohup script.sh &>/tmp/script.log &
プロセスが detache を受けたかどうかを二重に確認するには、次のように実行してください:
ps -efj --forest
そして、階層的なプロセス ツリーを見てください
0 Nikolas 2020-08-12
多くの回答はnohupを使用することを示唆しています。私はむしろ pm2 を使うことをお勧めします。nohup よりも pm2 を使うことで、アプリケーションを生きたまま維持したり、アプリケーションのログファイルを維持したり、他の多くの機能を利用したりと、多くの利点があります。詳細については、これをチェックアウト
pm2 をインストールするには npm をダウンロードする必要があります。Debian ベースのシステムの場合
sudo apt-get install npm
とRedhatのために
sudo yum install npm
または、これらの命令に従うことができます。npm をインストールした後、pm2 をインストールするためにそれを使ってください
npm install pm2@latest -g
それが完了したら、あなたはあなたのアプリケーションを開始することができます
$ pm2 start app.js # Start, Daemonize and auto-restart application (Node)
$ pm2 start app.py # Start, Daemonize and auto-restart application (Python)
プロセスの監視には、以下のコマンドを使用します
$ pm2 list # List all processes started with PM2
$ pm2 monit # Display memory and cpu usage of each app
$ pm2 show [app-name] # Show all informations about application
アプリ名またはプロセスIDでプロセスを管理するか、すべてのプロセスをまとめて管理します
$ pm2 stop <app_name|id|'all'|json_conf>
$ pm2 restart <app_name|id|'all'|json_conf>
$ pm2 delete <app_name|id|'all'|json_conf>
ログファイルは以下の場所にあります
$HOME/.pm2/logs #contain all applications logs
-1 haccks 2017-02-15
もしあなたの目的が、ターミナルウィンドウを囲わずに単にコマンドラインアプリケーションを起動することであるならば、ターミナルを起動した後にalt-F2でアプリケーションを実行してみるといいかもしれません
-1 MattKelly 2017-04-05