2009-03-23 11:59:25 +0000 2009-03-23 11:59:25 +0000
311
311

ターミナルからプロセスを完全に切り離すにはどうすればいいですか?

私は Ubuntu の Tilda (ドロップダウンターミナル) を「コマンドセンター」として使用しています。例えば、「適切な」ターミナルウィンドウで Vim を起動するために、次のような簡単なスクリプトを試してみました:

exec gnome-terminal -e "vim $@" &> /dev/null &

しかし、これでもまだ汚染を引き起こしています (また、ファイル名を渡してもうまくいかないようです)。

回答 (18)

355
355
355
2009-03-23 13:18:35 +0000

まず第一に、一度処理を開始したら、まず処理を停止して(Ctrl-Zを打つ)、bgと入力してバックグラウンドで再開させることができます。これで「ジョブ」となり、そのstdout/stderr/stdinはまだターミナルに接続されています。

最後に"&“をつけることで、すぐにバックグラウンドでプロセスを開始することができます:

firefox &

無音でバックグラウンドで実行するには、これを使用してください:

firefox </dev/null &>/dev/null &

いくつかの追加情報です。

nohup は、アプリケーションを実行するのに***を使うことができるプログラムです。しかし、アプリケーションを起動する前にこれを使用する先見の明が必要です。

nohup はシェルのジョブリストからシェルのジョブを削除する bash ビルトインです。これが基本的に意味するのは、disown, fgをその子に使えなくなったということですが、もっと重要なことは、シェルを閉じたときにハングしたり、その子にbgを送ったりしなくなったということです。SIGHUP とは異なり、nohup はプロセスが起動されてバックグラウンド化された**後に使用されます。

できないことは、プロセスを起動した後にプロセスの標準出力/stderr/stdin を変更することです。少なくともシェルからはできません。プロセスを起動して、その標準出力をターミナルに設定した場合 (デフォルトではそうなっています)、そのプロセスはターミナルに出力されるように設定されています。シェルはプロセスの FD 設定とは何の関係もありません。プロセス自身は、stdout/stderr/stdin を閉じるかどうかを決めることができますが、シェルを使って強制的に閉じさせることはできません。

バックグラウンドプロセスの出力を管理するには、スクリプトから多くのオプションがあります。しかし、起動しているのに黙らせるのを忘れてしまった対話的なプロセス (disown) には、あまり何もできません。screen を使えば、プロセスの出力が面倒になったら実行中のシェルを閉じて、新しいシェルを開くことができます (


あ、ちなみに ”firefox < /dev/null &>/dev/null &“ は使うところでは使わないでください。

screen は、^Ac, $@, $@, $1 …という意味で、以下のようになります。

あなたが与えた($2 を使った)シナリオでは、複数の引数を適切に動作させるのは本当に難しいです。引数を一つにエンコードしなければなりません。最良で最も堅牢な方法は、以下のようになります:

gnome-terminal -e "vim $1" "$2" "$3" ...
202
202
202
2009-03-23 12:17:32 +0000
nohup cmd &

nohup プロセスを完全に切り離します(デーモン化)

62
62
62
2009-03-23 12:05:02 +0000

もし、bashを使っているのであれば、disown [jobspec]を試してみてください; bash(1) を参照してください。スーパーユーザでない場合、at now の使用許可が制限されている可能性があります。

41
41
41
2014-01-22 17:08:16 +0000

これらの回答を読んで、私は最初、nohup <command> &を発行すれば十分だと思っていました。gnome-terminal で zsh を実行してみると、nohup <command> & はシェルが終了時に子プロセスを kill するのを防いでいないことがわかりました。nohup は特に非インタラクティブなシェルでは便利ですが、この動作を保証するのは、子プロセスが SIGHUP シグナルのハンドラをリセットしない場合だけです。

私の場合、nohup はハングアップシグナルがアプリケーションに到達するのを防ぐはずでしたが、子アプリケーション (この場合は VMWare Player) は SIGHUP ハンドラをリセットしていました。その結果、ターミナルエミュレータが終了したときに、まだあなたのサブプロセスを殺すことができました。これは、私の知る限りでは、シェルのジョブテーブルからプロセスを削除することによってのみ解決できます。nohupがシェルの組み込み関数でオーバーライドされている場合、時々そうであるように、これは十分かもしれませんが、そうでない場合には…


disownはシェルの組み込み関数で、bash, zsh, ksh93,

<command> &
disown

または <command> &; disown

のように、ワンライナーを好む場合には、

&001

です。これは、ジョブテーブルからサブプロセスを削除するという一般的に望ましい効果を持っています。これにより、誤って子プロセスに全くシグナルを出さずにターミナルエミュレータを終了することができます。SIGHUP ハンドラがどのように見えようとも、これは子プロセスを殺してはいけません。

disown の後、プロセスはまだターミナルエミュレータの子プロセスですが(これを動作中に見たい場合は pstree で遊んでください)、ターミナルエミュレータが終了した後、init プロセスに接続されているのを見るべきです。言い換えれば、すべてがあるべき姿であり、おそらくあなたが望んでいる通りになっているということです。

  1. disownscreen はこの問題を解決することができますが、それらは非常に重く、このような単純なタスクのためにそれらを実行するのは嫌です。これらは、一般的にリモートマシン上で tty をメンテナンスしたい場合には、より適しています。多くのユーザにとって、シェルが zsh の tmux のような機能をサポートしているかどうかを確認することが望ましいかもしれません。これは、シェルが終了するときにジョブテーブルのジョブに setopt nohup を送信しないように指定するために使うことができます。シェルを終了する直前にこれを適用するか、常に有効にしておきたい場合は SIGHUP のようにシェルの設定に追加することができます。ジョブテーブルを編集する方法を探す。これをする方法が~/.zshrctcshでは見つけられなかったので、少々気になるところです。フォークオフする小さなC言語のプログラムを書いてcsh。これは非常に貧弱な解決策ですが、ソースは数十行で構成されているはずです。そうすれば、コマンドをコマンドラインの引数として C プログラムに渡すことができるので、ジョブテーブルのプロセス固有のエントリを避けることができます。
30
30
30
2015-08-25 14:39:31 +0000
  1. nohup $COMMAND &
  2. $COMMAND & disown
  3. setsid command

私は2番をずっと使ってきましたが、3番でも同様に動作します。また、disownnohupのフラグを持っていて、-hですべてのプロセスをdisownすることができ、-aで実行中のすべてのプロセスをdisownすることができます。

サイレンシングは-arによって達成されます。

9
9
9
2017-05-05 11:55:05 +0000

bashの最もシンプルで唯一の正解:

command & disown

ターミナルからプロセスを切り離す必要はありませんが、シェルから切り離す必要はありません。

9
9
9
2009-03-23 14:55:15 +0000

これは、ジョブリストから firefox を削除しますが、まだターミナルに縛られています。

7
7
7
2012-08-07 05:18:25 +0000

シェルを切り離すには、サブシェルからコマンドを実行します。例:

(command)

終了時に端末を閉じてもプロセスは生きています。

5
5
5
2013-05-22 23:00:56 +0000

ジョブのバックグラウンド化とフォアグラウンド化は、おそらくすべての Unix システム管理者が最初に知っておくべきことの一つでしょう。

4
4
4
2009-03-23 12:03:50 +0000

あなたはnohupコマンドを使用してコマンドを実行することができます、これはあなたのプロセスを切り離し、指定されたファイルに出力をリダイレクトします…しかし、私はそれが正確にあなたが必要とするものであるかどうかを確認していません…

2
2
2
2018-02-05 16:14:17 +0000

これを bashrc/zshrc に追加します:

detach() {
  "$@" 1>/dev/null 2>/dev/null &; disown
}

そうすれば、以下のように勘当されたコマンドを実行することができます:

detach gedit ~/.zshrc
2
2
2
2009-03-23 12:10:49 +0000

試してみてください daemon – あなたのフレンドリーなパッケージマネージャから利用可能で、端末から自分自身を切り離すためのあらゆる方法を包括的に世話してくれるはずです。

1
1
1
2015-06-14 17:53:47 +0000

私の.bashrcには、まさにその目的のために以下の関数があります:

function run_disowned() {
    "$@" & disown
}

function dos() {
    # run_disowned and silenced

    run_disowned "$@" 1>/dev/null 2>/dev/null
}

コマンドをターミナルから切り離して実行するために、dos をプレフィックスにします。

0
0
0
2010-06-19 16:46:44 +0000

Mac OS Xでは、ターミナルで子プロセスが引き裂かれないようにするには、nohup AND disownの両方を使う必要があることがわかりました。

0
0
0
2014-09-21 04:42:43 +0000

これを行うために以下のスクリプトを使用しています。端末への印刷処理を停止し、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
>>> run false
false
Error: false
>>> echo $?
1
>>> run true
true
>>> run sleep 10
sleep 10
>>>
0
0
0
2019-06-21 07:14:46 +0000

sudo apt install ucommon-utils

pdetach command

そこに行きましょう :)

-1
-1
-1
2017-02-15 04:16:48 +0000

多くの回答は nohup を使うことを提案しています。私はむしろ pm2 を使うことを提案します。nohupよりもpm2_を使うことで、アプリケーションを生きたまま維持したり、アプリケーションのログファイルを管理したり、他にも多くの利点があります。詳細は check this out .

pm2 をインストールするには npm をダウンロードする必要があります。Debian ベースのシステムのために

sudo apt-get install npm

と Redhat のために

sudo yum install npm

またはあなたは これらの指示 に従うことができます。npm_ をインストールした後、それを使用して pm2 をインストールするために 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
-1
-1
2017-04-05 13:47:37 +0000

もしあなたの目的が、ターミナルウィンドウを囲わずに単にコマンドラインアプリケーションを起動することであるならば、ターミナルを起動した後にalt-F2でアプリケーションを実行してみるといいかもしれません。

関連する質問

7
6
10
11
5