LinuxでSSHクライアントを閉じた後にバックグラウンドプロセスが停止しないようにする方法


291

SSH(Putty)を介してLinuxマシンで作業しています。プロセスを夜間実行したままにする必要があるので、プロセスをバックグラウンドで開始し(コマンドの最後にアンパサンドを付けて)、stdoutをファイルにリダイレクトすることでそれができると思いました。

驚いたことに、それはうまくいきません。Puttyウィンドウを閉じるとすぐに、プロセスが停止します。

どうすればそれを防ぐことができますか?

回答:


301

nohup」プログラムをチェックしてください。


4
その後どうやって止めますか?
Derek Dahmer、2013

9
ログインして「kill <pid>」を実行します。pidがわからない場合は、「pidof」を使用します。
JesperE 2010

32
を使用nohup command > /dev/null 2>&1 &して、stdoutまたはstderr出力を作成せずにバックグラウンドで実行できます(nohup.outファイルなし)
KCD

入力が必要な場合はどうなりますか?たとえば、バックグラウンドで実行する必要がある実行時間の長いスクリプトがありますが、最初にFTPパスワードを要求します。nohupこの場合は役に立ちません。Ctrl+Z/ をいじる方法はありbgますか?
セルゲイ

1
私は文字の不可解なシーケンスを覚えるのが面倒くさいので、@ KCDが言ったことに基づいてこれを書き、それをたくさん使ってきました。
アノマリー2015年

167

GNU Screenの使用をお勧めします。すべてのプロセスの実行を継続しながら、サーバーから切断できます。私はそれが存在することを知る前に、それなしでどのように生活していたのかわかりません。


7
これは、私が今まで使ったソフトウェアの中で最も素晴らしいものの1つです。真剣に。私はどこからでもsshを実行するBSDボックスで実行しており、画面に再接続してすべての端末であらゆる種類のことを実行できます。
アダムJaskiewicz 2008年

1
私はこれを証明することができます。画面は素晴らしいアプリケーションです。再接続する機能は驚くべきものであり、失われる可能性のある多くの作業を保存します。
willasaywhat 2008年

私はそれをローカルマシンで使用し、複数のxtermを同じスクリーンセッションに接続しています(screen -x)。そうすれば、スクリーンセッション内で多くのウィンドウを開いて、さまざまなxtermをウィンドウからウィンドウに自由に切り替えることができます。
アダムJaskiewicz 2008年

17
バックグラウンドアプリに再接続する必要があるかどうかによって異なります。そうすれば、ええ、スクリーンは飛行する唯一の方法です。でも、それが一生忘れられないのであれば、nohupは同じようにうまく機能します。
Dave Sherohman、2008年

1
画面の+1。または、別の方法として、tmux(これはscreenよりも好きです)またはbyobuです。これは、screenまたはtmuxの優れたフロントエンドです。screenと入力して、いつでもシェルを使用して後で戻るか、「screen command」のようにscreenを使用してコマンドを実行できます。プロセス「command」が存在する限り、スクリーンセッションは存在しますとても長いので、いつでも戻って標準出力を見ることができます。
gerlos、2014

81

セッションが閉じられると、プロセスはSIGHUPシグナルを受信しますが、それは明らかにキャッチしていません。nohupプロセスの起動時にコマンドを使用するかdisown -h、プロセスの開始後にbash組み込みコマンドを使用して、これが発生しないようにすることができます。

> help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.

4
ここでの利点は、既に開始されているプロセスに対してdisownが機能することです。
クリスチャンK.

1
「jobspec」はpidを意味しますか?
スチュワート

1
心配、ここでこの答えは見つかりませんstackoverflow.com/questions/625409/...
スチュワート

42

デーモン化?だめ?画面?(tmux ftw、画面はジャンクです;-)

他のすべてのアプリが最初から行っていることを実行してください-ダブルフォークです。

# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid:   1
# jobs
# disown
bash: disown: current: no such job

バン!完了:-)私は、あらゆる種類のアプリと多くの古いマシンでこれを数え切れないほど使用しました。リダイレクトと組み合わせて、プロセスとの間にプライベートチャネルを開くことができます。

coproc.shとして作成します。

#!/bin/bash

IFS=

run_in_coproc () {
    echo "coproc[$1] -> main"
    read -r; echo $REPLY
}

# dynamic-coprocess-generator. nice.
_coproc () {
    local i o e n=${1//[^A-Za-z0-9_]}; shift
    exec {i}<> <(:) {o}<> >(:) {e}<> >(:)
. /dev/stdin <<COPROC "${@}"
    (("\$@")&) <&$i >&$o 2>&$e
    $n=( $o $i $e )
COPROC
}

# pi-rads-of-awesome?
for x in {0..5}; do
    _coproc COPROC$x run_in_coproc $x
    declare -p COPROC$x
done

for x in COPROC{0..5}; do
. /dev/stdin <<RUN
    read -r -u \${$x[0]}; echo \$REPLY
    echo "$x <- main" >&\${$x[1]}
    read -r -u \${$x[0]}; echo \$REPLY
RUN
done

その後

# ./coproc.sh 
declare -a COPROC0='([0]="21" [1]="16" [2]="23")'
declare -a COPROC1='([0]="24" [1]="19" [2]="26")'
declare -a COPROC2='([0]="27" [1]="22" [2]="29")'
declare -a COPROC3='([0]="30" [1]="25" [2]="32")'
declare -a COPROC4='([0]="33" [1]="28" [2]="35")'
declare -a COPROC5='([0]="36" [1]="31" [2]="38")'
coproc[0] -> main
COPROC0 <- main
coproc[1] -> main
COPROC1 <- main
coproc[2] -> main
COPROC2 <- main
coproc[3] -> main
COPROC3 <- main
coproc[4] -> main
COPROC4 <- main
coproc[5] -> main
COPROC5 <- main

そして、あなたは行き​​ます、何でもスポーンします。<(:)はプロセスの置換を介して匿名パイプを開きますが、これは終了しますが、ハンドルがあるためパイプはそのまま残ります。私は通常行うsleep 1代わりにし:て、わずかに際どいので、私は「ファイル使用中」エラーを取得したい-実際のコマンドが実行された(例えば、ある場合に起こることはありませんcommand true

「ヘレドックソーシング」:

. /dev/stdin <<EOF
[...]
EOF

これは、busybox / etc(initramfs)を含め、これまでに試したすべてのシェルで機能します。私はそれが以前に行われたのを見たことがない、私はソースを渡すことができることを知っていた誰がソースを引数にとることができるか知っていたときに、それを独立して発見しましたか?しかし、そのようなことがあった場合、それはしばしばevalのはるかに扱いやすい形式として機能します。


2
なぜ反対票...それで質問が古い場合はどうなりますか?他に11の悪い答えがあるとすれば、それは明らかに関連性があります。このソリューションは、systemdではなく、過去30年間デーモン化する慣用的で受け入れられた方法であり、無意味なアプリではありません。nohup et al。
anthonyrisinger

7
あなたの答えがどれほど優れていても、SOの誰かがそれを気に入らず、反対票を投じる場合があります。あまり気にしない方がいいです。
Alex D

1
@ tbc0 ... tryssh myhost "((exec sleep 500)&) >/dev/null"
anthonyrisinger 2013年

1
@anthonyrisingerわかりました。私は、これはきれいだと思う:ssh myhost 'sleep 500 >&- 2>&- <&- &' TMTOWTDI;)
TBC0

1
これは素晴らしい。busyboxで実際に機能する唯一のソリューション。それはより多くの賛成票に値します
Hamy

34
nohup blah &

何とかしてプロセス名を置き換えてください!


2
リダイレクト標準出力と標準エラーを追加したい場合があります。
David Nehme 2008年

9
nohupはstdoutとstderrをnohup.out(またはバージョンによってはnohup.outとnohup.err)にリダイレクトします。そのため、複数のコマンドを実行しているのでない限り、それは必要ありません。
Chas。オーエンス

17

個人的には、「バッチ」コマンドが好きです。

$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D

これはバックグラウンドに詰め込み、結果をメールで送信します。これはcronの一部です。


11

他の人が指摘したように、SSHセッションから切断できるようにバックグラウンドでプロセスを実行するには、バックグラウンドプロセスを制御端末から適切に切り離す必要があります。これは、SSHセッションが使用する疑似ttyです。

デーモン化プロセスに関する情報は、Stevensの「Advanced Network Program、Vol 1、3rd Edn」やRochkindの「Advanced Unix Programming」などの本にあります。

私は最近(ここ数年)、自分自身を適切にデーモン化しない反抗的なプログラムに対処する必要がありました。nohupに似ていますが、より多くのコントロールが利用可能である、一般的なデーモン化プログラムを作成することで、私はそれを処理することになりました。

Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...]
  -V          print version and exit
  -a          output files in append mode (O_APPEND)
  -b          both output and error go to output file
  -c          create output files (O_CREAT)
  -d dir      change to given directory
  -e file     error file (standard error - /dev/null)
  -h          print help and exit
  -i file     input file (standard input - /dev/null)
  -k fd-list  keep file descriptors listed open
  -m umask    set umask (octal)
  -o file     output file (standard output - /dev/null)
  -s sig-list ignore signal numbers
  -t          truncate output files (O_TRUNC)
  -p          print daemon PID on original stdout
  -x          output files must be new (O_EXCL)

二重ダッシュは、GNU getopt()関数を使用しないシステムではオプションです。Linuxなどでは必要です(または環境でPOSIXLY_CORRECTを指定する必要があります)。ダブルダッシュはどこでも機能するため、使用することをお勧めします。

のソースが必要な場合は、私(firstname dot lastname at gmail dot com)に連絡できますdaemonize

ただし、コードは(最終的に)SOQ(Stack Overflow Questions)リポジトリのGitHub daemonize-1.10.tgzpackages サブディレクトリにあるファイルとして利用できるようになりました。


13
ソースをgithubやbitbucketに入れてみませんか?
Rob

5
なぜgithubからのソースの欠如が反対投票を正当化するのですか?
ジョナサンレフラー

7
@JonathanLeffler IMHOは、どのような形でも(商業的にも)公開されていないプログラムのすべてのクールなオプションをリストし、読者の時間を浪費することに境界を定めています。
DepressedDaniel 2017

7

Debianベースのシステム(リモートマシン)にインストールします。

sudo apt-get install tmux

使用法:

tmux

必要なコマンドを実行する

セッションの名前を変更するには:

Ctrl + B、次に$

名前を設定

セッションを終了するには:

Ctrl + B、続いてD

(これによりtmuxセッションが終了します)。その後、SSHからログアウトできます。

もう一度戻って確認する必要がある場合は、SSHを起動して次のように入力します。

tmux attach session_name

tmuxセッションに戻ります。


これが先の方法です
kilgoretrout 2018年

6

ほとんどのプロセスでは、この古いLinuxコマンドライントリックを使用して疑似デーモン化できます。

# ((mycommand &)&)

例えば:

# ((sleep 30 &)&)
# exit

次に、新しいターミナルウィンドウを起動して、

# ps aux | grep sleep

sleep 30まだ実行中であることが表示されます。

あなたがしたことは、プロセスを子の子として開始することであり、終了するとき、nohup通常プロセスを終了させるトリガーとなるコマンドは孫にカスケードされず、孤立したプロセスとして残り、実行されます。

私はこの「それを設定し、それを忘れて」アプローチ、対処する必要はありません好むnohupscreenI / Oリダイレクション、tmuxのを、またはその原料のいずれか。


5

screenを使用してrootとしてプロセスを実行する場合は、特権昇格攻撃の可能性に注意してください。自分のアカウントが何らかの形で侵害された場合、サーバー全体を乗っ取る直接的な方法があります。

このプロセスを定期的に実行する必要があり、サーバーに十分なアクセス権がある場合は、cronを使用してジョブを実行することをお勧めします。init.d(スーパーデーモン)を使用してプロセスをバックグラウンドで開始することもできます。終了するとすぐに終了できます。


5

nohup詳細をファイルに記録する場合は、非常に便利です。しかし、バックグラウンドになると、スクリプトが要求した場合にパスワードを与えることができません。やってみないといけないと思いますscreen。そのユーティリティは、たとえばCentOSのyumを使用してLinuxディストリビューションにインストールしてyum install screenから、シェルタイプでputtyまたは別のソフトウェアを介してサーバーにアクセスできますscreen。画面[0]をパテで開きます。仕事をしなさい。同じパテセッションでさらにscreen [1]、screen [2]などを作成できます。

知っておくべき基本的なコマンド:

スタート画面

画面


C reate次の画面

Ctrl + A + C


移動するにはn個作成した内線画面

Ctrl + A + N


D etach

Ctrl + A + D


作業中はパテを閉じます。そして次回パテタイプでログインするとき

画面-r

画面に再接続すると、画面上で実行中のプロセスを確認できます。画面を終了するには、#exitと入力します。

詳細については、を参照してくださいman screen


それyumが適切なツールであると仮定すると、ディストリビューションがわからない場合は適切ではありません。screenでインストールできるディストリビューションを明確にする必要がありますyum
tymik

5

Nohupは、ログアウト時の引数として、親プロセスが強制終了された場合にクライアントプロセスを強制終了しないようにします。さらにより良い使用:

nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG  " > /dev/null

Nohupは、SSHセッションとその子プロセスがログアウト時に強制終了される終了の影響を受けないプロセスを作成します。私が与えたコマンドは、アプリケーションのpidをpidファイルに保存する方法を提供します。これにより、後でそれを適切に強制終了し、ログアウト後にプロセスを実行できます。




2

私もスクリーンプログラムに行きます(他にsome1の答えがスクリーンだったことはわかっていますが、これは完了です)

&、ctrl + z bg disown、nohupなどがログオフしたときにジョブが依然として殺されるという厄介な驚きを与えるかもしれないという事実だけでなく(なぜ私は知らないが、それは私に起こりました、そしてそれは気にしませんでした)それが原因で私は画面を使用するように切り替えましたが、二重分岐がそれを解決するので、私はanthonyrisingerソリューションを推測します)、また、画面には単なるバックグラウンドよりも大きな利点があります:

screen will background your process without losing interactive control to it

ところで、これは私が最初に尋ねることは決してない質問です:) ...私は任意のUNIXで何でも最初から画面を使用しています...私は(ほとんど)画面を起動せずにUNIX / Linuxシェルで作業することはありません最初に...そして私は今止めるべきです、そうでなければ私は何が良い画面で何ができるかについての無限のプレゼンテーションを始めます...自分でそれを調べてください、それは価値があります;)


PS anthonyrisinger、あなたはいいです、私はあなたにそれを与えますが... 30年ですか?&、bg、nohup、screenがまだ存在しない場合の解決策だと思います。問題はありません。知識はありがたいですが、複雑すぎて使用できません:)
THESorcerer

2
(余談:Tmuxを参照してくださいこれは私(1987年)よりもかなり前から存在しますが、&(非同期実行)は、UNIX の最初のバージョン用にThompsonシェルによって1971年に導入されまし ... したがって、文字通り「常に存在していた」 ;-)ああ、私はあまりにも保守的でした-それは実際には41年になります。
anthonyrisinger

2

オープンソースのlibslackパッケージのデーモンコマンドもあります。

daemon 非常に構成可能であり、自動再起動、ロギング、pidfile処理などの面倒なデーモンのすべてを処理します。


2

次の文字列をコマンドに追加します:>&-2>&-<&-&。>&-はstdoutを閉じることを意味します。2>&-はstderrを閉じることを意味します。<&-は標準入力を閉じることを意味します。&はバックグラウンドで実行することを意味します。これは、sshを介してプログラムでジョブを開始する場合にも機能します。

$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$


1

受け入れられた答えは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

バイナリ実行可能ファイルは、pm2を使用して実行することもできます。jasonファイルを変更する必要があります。変更"exec_interpreter" : "node"するために、"exec_interpreter" : "none".(参照属性セクションを)。

#include <stdio.h>
#include <unistd.h>  //No standard C library
int main(void)
{
    printf("Hello World\n");
    sleep (100);
    printf("Hello World\n");

    return 0;
}

上記のコードをコンパイルする

gcc -o hello hello.c  

そしてそれをバックグラウンドでnp2で実行します

pm2 start ./hello

これを使用してバイナリ実行可能ファイルを実行できますか?
GetFree

@自由になる; はい。あなたはできる。
2017

例を追加してください。現時点での答えは、スクリプトファイルにのみ適しているようです。
GetFree 2017

@自由になる; 例を追加しました。問題がある場合はお知らせください。
2017

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.