SSH接続を介してLinuxサーバーで数日間、計算タスクを実行しています。バックグラウンドではないため、SSH接続はタスクの保留中です。
Sshセッションを開いたローカルマシン(サーバーではない)を再起動したいが、タスクを実行したままにしたい。それは可能ですか?
タスクがすでに起動されている場合は、手遅れです*
ssh
セッションと、コマンドを実行するシェルの間にscreen
、tmux
、byobu
、Nohup
などの追加のレイヤーを挿入する代替ソリューションを検討します。
プロセスサポートをバックグラウンドで配置する場合、特に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、 retty 、 injcode および neercs 。最も高度なように見えるのは reptyr ですが、ptraceがプロセスをハッキングできるようにするには、root権限が必要になる場合があります。
1つの解決策は GNU screen を使用することです。 screen
を起動し、コマンドを実行してから、C-a d
でデタッチできます。後で再接続するには、screen -r
を実行すると、前のセッションに戻ります。
画面のその他の利点はウィンドウ管理であり(新しいSSH接続を必要とせずに、コマンドの実行中に他のシェルに切り替えることができます)、現在のセッションでも後のセッションでも、コマンドをフォアグラウンドに残すことができます。
編集:コメントに記載されているように、これは、コマンドを実行する前にscreen
を開始することを忘れない場合にのみ機能します。コマンドがすでに実行されている場合は、@ jlliagreのソリューションが必要になります。
これを行う「標準」の方法の1つは、次のように、Nohup
に含まれているcoreutils
コマンドを使用することです。
Nohup COMMAND [ARGS] &
ただし、このコマンドはプログラムの出力(STDOUT
&STDERR
AFAIK)をファイルNohup.out
にリダイレクトするため、(巨大なログファイルを生成するなど)面倒なことがあります。独自のリダイレクトを作成するか、必要に応じて/ dev/nullにリダイレクトすることができます。
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