SSHからログアウトした後、現在実行中のLinuxタスクが強制終了されるのを防ぐ


18

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

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

回答:


22

あなたのタスクがすでに起動された場合、手遅れになる*代替ソリューションを検討しているあなたとの間に追加の層を挿入しsshたセッションとシェルがコマンドを実行している、のようなscreentmuxbyobunohupと同類。

あなたのプロセスのサポートは、バックグラウンドに配置する場合は、特にときハングしないstdoutstderr書き込みできない/が閉鎖され、あなたがログアウトする前に、バックグラウンドでそれを置くことができます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
$ 

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


Ctrl + Zを使用し、ジョブを停止してバックグラウンドに移動し、disownコマンドを実行しました。bash:警告:プロセスグループ24876で停止したジョブ1を削除します。現在、私のジョブはリストされてps -allいますが、動作していないようです(CPU使用率は0%)
アリ

プロセスが停止しているようです。私は私がプロセスへのIDを提供している必要がありますねdisownコマンド
アリ

@Ali中断されたジョブを再開するためにbgコマンドを実行するのを忘れたと思います。
ジェイソン朱14年

1
@JasonZhuそれを指摘してくれてありがとう。bg返信の最初の部分でコマンドが必要かどうかは不明でした。編集済み。
jlliagre 14年

2
bgコマンドを忘れてdisownコマンドのみを実行した場合、bgとkill -CONTほぼ同じプロセスを再び実行できるようになります。
カスペルド14年

5

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

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

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


2
tmuxこのような別のプログラムscreenは、現在のSSH接続に関連付けられていないリモートセッションを持つことを可能にします。
ダースアンドロイド14年

2
あなたのソリューションは素晴らしいです。しかし、それは私の質問に完全に適合していません-私は現在実行中のプロセスについて尋ねましたscreen
アリ14年

うん、いいよ。その場合、@ jlliagreのソリューションを使用する必要があると思います。(私が知る限り、既に実行中のプロセスをscreenやなどに接続する方法はありませんtmux。)
Scott Weldon 14年

1

そのための「標準的な」方法の1つは、次のようにnohupに含まれるコマンドを使用するcoreutilsことです。

nohup COMMAND [ARGS] &

しかし、このコマンドはプログラムの出力(STDOUTSTDERRAFAIK)をファイルnohup.outにリダイレクトしますが、それはなんらかの面倒なこと(巨大なログファイルの生成など)になるため、独自のリダイレクトを行うか、/ dev / nullにリダイレクトすることをお勧めしますお望みならば。


2
もう一度読んでください。プロセスはすでに実行中です。
モニカとの軽さレース14

/ ashamedは注意深く読みませんでした。ごめんなさい。
wangguoqin1001 14年

実際nohupにこれに使用できます。実行中のプロセスを一時停止し、バックグラウンドに送信するだけで(Ctrl+ Zおよび実行bg)、発行できますnohup %1
マイク14年

0

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

コマンドの末尾に&を付け、括弧で囲みます

$ (thecommand args &)

プロセスがpid 1922を獲得したとしましょう:

$ 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から切断されます。

シェルを終了し、新しいシェルを入力してください。このシェルが同じPTSに接続されている場合でも、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.