web-dev-qa-db-ja.com

SSHからのログアウト後に現在実行中のLinuxタスクが強制終了されないようにする

SSH接続を介してLinuxサーバーで数日間、計算タスクを実行しています。バックグラウンドではないため、SSH接続はタスクの保留中です。

Sshセッションを開いたローカルマシン(サーバーではない)を再起動したいが、タスクを実行したままにしたい。それは可能ですか?

18
Ali

タスクがすでに起動されている場合は、手遅れです*sshセッションと、コマンドを実行するシェルの間にscreentmuxbyobuNohupなどの追加のレイヤーを挿入する代替ソリューションを検討します。

プロセスサポートをバックグラウンドで配置する場合、特にstdoutおよびstderrが書き込み不可/クローズされているときにハングしない場合は、ログアウトする前にバックグラウンドで実行できます。 ControlZ そしてbgは、disownビルトインを使用してシェルからデタッチします。

例えば:

$ ssh localhost
You have new mail.
Last login: Fri Jun  6 11:26:56 2014

$ /bin/sleep 3600    


^Z[1] + Stopped                  /bin/sleep 3600
$ bg
[1] /bin/sleep 3600&
$ jobs
[1] +  Running                 /bin/sleep 3600
$ disown %1
$ exit
Connection to localhost closed.
$ ps -ef|grep sleep
jlliagre 12864     1  0 21:12 ?        00:00:00 /bin/sleep 3600
jlliagre 13056 12477  0 21:13 pts/18   00:00:00 grep sleep
$ 

*ボブがコメントしたように、Linuxでttyセッションを再ペアレント化するための実際にはいくつかのハックな方法があります。 repty、 rettyinjcode および neercs 。最も高度なように見えるのは reptyr ですが、ptraceがプロセスをハッキングできるようにするには、root権限が必要になる場合があります。

22
jlliagre

1つの解決策は GNU screen を使用することです。 screenを起動し、コマンドを実行してから、C-a dでデタッチできます。後で再接続するには、screen -rを実行すると、前のセッションに戻ります。

画面のその他の利点はウィンドウ管理であり(新しいSSH接続を必要とせずに、コマンドの実行中に他のシェルに切り替えることができます)、現在のセッションでも後のセッションでも、コマンドをフォアグラウンドに残すことができます。

編集:コメントに記載されているように、これは、コマンドを実行する前にscreenを開始することを忘れない場合にのみ機能します。コマンドがすでに実行されている場合は、@ jlliagreのソリューションが必要になります。

5
Scott Weldon

これを行う「標準」の方法の1つは、次のように、Nohupに含まれているcoreutilsコマンドを使用することです。

Nohup COMMAND [ARGS] &

ただし、このコマンドはプログラムの出力(STDOUTSTDERR AFAIK)をファイルNohup.outにリダイレクトするため、(巨大なログファイルを生成するなど)面倒なことがあります。独自のリダイレクトを作成するか、必要に応じて/ dev/nullにリダイレクトすることができます。

1
wangguoqin1001

Nohupに加えて、「&」とサブシェルを使用してバックグラウンドでプロセスを起動できます。

コマンドに&をサフィックスし、括弧で囲みます

$ (thecommand args &)

あなたのプロセスがpid1922を獲得したとしましょう:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11473  2643  0 15:07 pts/1    00:00:00 bash
usr      11922     1  0 15:11 pts/1    00:00:00 thecommand

元の親であったシェルプロセス11473からアタッチされていないことを確認してください。したがって、現在のシェル(11473)を終了または強制終了すると、プロセス11922は実行を継続し、ptsから切断されます。

シェルを終了して、新しいシェルに入るようにしてください。このシェルが同じポイントに接続されている場合でも、ポイントなしでプロセスを確認できます。

$ ps -fp 11922
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11922     1  0 15:11 ?        00:00:00 thecommand

Posixでの呼び出し方法や文書化方法はわかりませんが、1990年以降、bsh、ksh、そして現在はbashでこの方法を使用しています。

最後に、bg組み込みシェルコマンドを使用できます:

プログラムを起動するだけで、一時停止する場合、またはバックグラウンドで保持する場合は、CTRL + Zを入力します。

$ thecommand
^Z
[1] Stopped          thecommand

次に、バックグラウンドで実行し続けます。

$ bg
[1]+ thecommand &

プロセス情報を見ると、まだ親プロセスがあります。

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12046  2643  0 15:18 pts/6    00:00:00 bash
usr      12571 12046  0 16:00 pts/6    00:00:00 thecommand
usr      12601 12046  0 16:04 pts/6    00:00:00 ps -f

したがって、現在のプロセスを終了します。バックグラウンドで実行中のプロセスは、元の親からアタッチされておらず、バックグラウンドで実行を続けます。

$ exit

再度ログインして、プロセス情報を確認してください。

$ ps -f 12571
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12571     1  0 16:00 ?        00:00:00 thecommand
0
Luciano