Linuxで、SSHクライアントを閉じた後にバックグラウンドプロセスが停止しないようにする方法
-
08-07-2019 - |
質問
SSH(Putty)を介してLinuxマシンで作業しています。 夜中にプロセスを実行したままにする必要があるので、バックグラウンドでプロセスを開始し(コマンドの最後にアンパサンドを使用)、stdoutをファイルにリダイレクトすることでそれができると考えました。 驚いたことに、それは機能しません。 Puttyウィンドウを閉じるとすぐにプロセスが停止します。
どうすればそれを防ぐことができますか?
解決
<!> quot; nohup <!> quot;をご覧ください。プログラム。
他のヒント
GNU画面の使用をお勧めします。すべてのプロセスの実行を継続しながら、サーバーから切断できます。私はそれが存在することを知る前に、私はそれなしでどのように生きたかを知りません。
セッションが閉じられると、プロセスは明らかにキャッチしていないSIGHUPシグナルを受信します。プロセスの起動時にnohup
コマンドを使用するか、プロセスの開始後にbash組み込みコマンドdisown -h
を使用して、これを防ぐことができます。
> 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.
daemonize?いや?画面? (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
そして、そこに行き、何でもスポーンします。 <!> lt;(:)は、プロセス置換を介して匿名パイプを開きますが、これは終了しますが、パイプはハンドルを持っているため保持されます。私は通常sleep 1
の代わりに:
を使用しますが、これは少し際どいため、<!> quot; file busy <!> quot;エラー-実際のコマンドが実行された場合(たとえば、command true
)
<!> quot; heredoc sourcing <!> quot;:
. /dev/stdin <<EOF
[...]
EOF
これは、busybox / etc(initramfs)など、これまでに試したすべてのシェルで機能します。ソースを引数として受け入れることができることを知っていたので、私はそれを前に見たことがありません。しかし、そのようなことがある場合、それはしばしばはるかに管理しやすいevalの形式として機能します。
nohup blah &
プロセス名をblahに置き換えてください!
個人的には、「バッチ」コマンドが好きです。
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
これはバックグラウンドにそれを詰め込み、結果をあなたにメールします。 cronの一部です。
他の人が指摘したように、SSHセッションから切断できるようにバックグラウンドでプロセスを実行するには、バックグラウンドプロセスを制御端末から適切に分離する必要があります-これはSSHセッションの擬似ttyです使用します。
デーモン化プロセスに関する情報は、Stevensの<!> quot; Advanced Network Program、Vol 1、3rd Edn <!> quot;などの本で見つけることができます。またはRochkindの<!> quot; Advanced Unix Programming <!> quot;。
最近(ここ数年)、自分自身を適切にデーモン化しなかった扱いにくいプログラムに対処しなければなりませんでした。最終的には、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を指定する必要があります)。二重ダッシュはどこでも機能するため、使用するのが最適です。
daemonize
のソースが必要な場合は、私に連絡することもできます(ファーストネームドットラストネームgmailドットコム)。
ただし、GitHubの SOQ (Stack
オーバーフロー質問)ファイルdaemonize-1.10.tgz
としてのリポジトリ
パッケージ
サブディレクトリ。
スクリーンを使用してプロセスをルートとして実行する場合、特権の昇格攻撃の可能性に注意してください。自分のアカウントが何らかの方法で侵害された場合、サーバー全体を引き継ぐ直接的な方法があります。
このプロセスを定期的に実行する必要があり、サーバーに十分なアクセス権がある場合は、cronを使用してジョブを実行することをお勧めします。また、init.d(スーパーデーモン)を使用して、プロセスをバックグラウンドで開始することもできます。プロセスが完了するとすぐに終了できます。
Debianベースのシステム(リモートマシン上) インストール:
sudo apt-get install tmux
使用法:
tmux
必要なコマンドを実行
セッションの名前を変更するには:
Ctrl + B 、次に $
名前の設定
セッションを終了するには:
Ctrl + B 、次に D
(これによりtmuxセッションが終了します)。その後、SSHからログアウトできます。
戻ってくる/もう一度確認する必要がある場合は、SSHを起動して入力してください
tmux attach session_name
tmuxセッションに戻ります。
nohup
は、詳細をファイルに記録する場合に非常に適しています。しかし、バックグラウンドになると、スクリプトが要求した場合、パスワードを与えることができません。 screen
を試す必要があると思います。そのユーティリティは、たとえばCentOS yum install screen
でyumを使用してLinuxディストリビューションにインストールし、シェルタイプman screen
でputtyまたは別のソフトウェアを介してサーバーにアクセスできます。パテでscreen [0]を開きます。仕事をしなさい。同じパテセッションで、より多くのscreen [1]、screen [2]などを作成できます。
知っておくべき基本的なコマンド:
画面を開始するには
画面
c 次の画面を作成するには
ctrl + a + c
作成した n ext画面に移動するには
ctrl + a + n
d 添付
するにはctrl + a + d
作業中にパテを閉じます。次回、パテタイプでログインするとき
screen -r
画面に再接続すると、画面上で実行中のプロセスを確認できます。画面を終了するには、#exitと入力します。
詳細については、<=>を参照してください。
ほとんどのプロセスでは、この古いLinuxコマンドライントリックを使用して擬似デーモン化できます。
# ((mycommand &)&)
例:
# ((sleep 30 &)&)
# exit
次に、新しいターミナルウィンドウを起動して、
# ps aux | grep sleep
sleep 30
がまだ実行中であることを示します。
あなたがやったことは、プロセスを子の子として開始し、終了すると、通常プロセスを終了させるnohup
コマンドは孫にカスケードされず、そのまま残ります孤立したプロセス、まだ実行中。
私はこれを好む<!> quot;それを設定して忘れる<!> quot;アプローチ、screen
、<=>、tmux、I / Oリダイレクト、またはそれらのいずれかを扱う必要はありません。
Nohupを使用すると、ログアウト時の引数として、親プロセスが強制終了された場合にクライアントプロセスが強制終了されません。さらに良い使用方法:
nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null
Nohupは、ログアウト時にSSHセッションとその子プロセスが強制終了する終了の影響を受けないようにします。私が与えたコマンドは、アプリケーションのpidをpidファイルに保存する方法を提供します。これにより、後でそれを強制終了でき、ログアウト後にプロセスを実行できます。
画面を使用します。使い方は非常に簡単で、端末のvncのように機能します。 http://www.bangmoney.org/presentations/screen.html
Xアプリケーションも実行する場合- xpra と<!> quot; screen < !> quot;。
iはスクリーンプログラムにも行きます(他の誰かの答えはスクリーンでしたが、これは完了です)
<!> amp;、ctrl + z bg disown、nohupなどの事実だけでなく、あなたがログオフジョブがまだ殺されるという厄介な驚きを与える可能性があります、それはスクリーンを使用するように切り替えたので気にしませんでしたが、ダブルフォークとしてのアントリシンガーソリューションがそれを解決すると思います)、スクリーンは単にバックグラウンディングよりも主要な利点があります
screen will background your process without losing interactive control to it
そしてところで、これは私が最初に尋ねることは決してない質問です:) ...私はunixで何かをする最初からスクリーンを使用します... i(ほとんど)unix / linuxシェルでは動作しません最初に画面を起動せずに...そして今すぐ停止する必要があります、または私は良い画面が何であり、yaのために何ができるのか無限のプレゼンテーションを開始します...自分で調べてください、それは価値があります;)
オープンソースlibslackパッケージの daemon コマンドもあります。
daemon
は非常に構成可能であり、自動再起動、ログ記録、pidfile処理などの退屈なデーモンのすべてを処理します。
この文字列をコマンドに追加します:<!> gt; <!> amp;-2 <!> gt; <!> amp;-<!> lt; <!> amp;-<!> amp;。 <!> gt; <!> amp;-は、標準出力を閉じることを意味します。 2 <!> gt; <!> amp;-は、stderrを閉じることを意味します。 <!> lt; <!> amp;-は、標準入力を閉じます。 <!> amp;バックグラウンドで実行することを意味します。これは、sshを介してプログラムでジョブを開始する場合にも機能します。
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
screenコマンドを使用しました。このリンクには、これを行う方法に関する詳細が記載されています
https://www.rackaid.com / blog / linux-screen-tutorial-and-how-to /#starting
受け入れられた答えは、 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
systemd / Linuxでは、 systemd-run はセッションに依存しないプロセスを起動するための素晴らしいツール。嫌いは嫌いだ