私はSSH(PuTTY)を介してLinuxマシンに取り組んでいます。私はプロセスを夜中に実行したままにする必要があるので、私はプロセスをバックグラウンドで開始し(コマンドの最後にアンパサンドを付けて)、標準出力をファイルにリダイレクトすることでそれを実行できると思いました。驚いたことに、それはうまくいきません。 PuTTYウィンドウを閉じるとすぐに、プロセスは停止します。
どうしたらそれを防ぐことができますか?
" Nohup "プログラムをチェックしてください。
私は GNU Screen を使うことを勧めます。それはあなたがあなたのプロセスのすべてが実行され続けている間あなたがサーバーから切断することを可能にします。私はそれが存在することを知る前に私はそれなしで生きていた方法がわからない。
セッションが閉じられると、プロセスは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.
デーモン化する?おっ?画面? (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
)
"heredocソーシング":
. /dev/stdin <<EOF
[...]
EOF
これは、busybox/etc(initramfs)を含む私が今までに試したすべてのシェルすべてで動作します。私はこれまでにそれが行われたのを見たことがない、私は独自にそれを発見している間に発見した。しかし、そのようなことがあれば、それはしばしばもっと管理しやすい形のevalとして役立ちます。
Nohup blah &
あなたのプロセス名をblahに置き換えてください。
個人的には、 'batch'コマンドが好きです。
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
これは背景にそれを詰め込み、そしてあなたに結果をメールで送ります。これはcronの一部です。
他の人が指摘したように、SSHセッションから切断できるようにバックグラウンドでプロセスを実行するには、バックグラウンドプロセスを制御端末から適切に分離する必要があります。これがSSHセッションで使用される疑似端末です。
プロセスのデーモン化に関する情報は、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を指定する必要があります)。
daemonize
のソースが必要な場合は、まだ私に連絡することができます(gmail dot comのfirstname dot lastname)。
しかし、コードは(ついに)私の SOQ (Stack Overflow Questions)リポジトリの packages サブディレクトリのファイルdaemonize-1.10.tgz
としてGitHubで利用可能になりました。
Debianベースのシステム(リモートマシン上)にインストールします。
Sudo apt-get install tmux
使用法:
tmux
必要なコマンドを実行する
セッション名を変更するには
Ctrl + B次に$
セット名
セッションを終了するには
Ctrl + B次にD
(これはtmuxセッションを離れます)。その後、SSHからログアウトできます。
また戻ってきたりチェックしたりする必要があるときは、SSHを起動して次のように入力します。
tmux attach session_name
Tmuxセッションに戻ります。
詳細をファイルに記録する場合は、Nohup
が非常に優れています。しかし、それがバックグラウンドになると、あなたのスクリプトが要求した場合、あなたはそれにパスワードを与えることができません。 screen
を試す必要があると思います。そのユーティリティはyumを使ってあなたのLinuxディストリビューションにインストールすることができます。例えばCentOSのyum install screen
そしてあなたのシェルタイプscreen
でPuTTYか他のソフトウェアを通してあなたのサーバーにアクセスしてください。 PuTTYで画面[0]が開きます。仕事をしなさい。同じPuTTYセッションで、より多くの画面[1]、画面[2]などを作成できます。
あなたが知る必要がある基本的なコマンド:
画面を起動する
c次の画面に移動する
nあなたが作成したext画面に移動する
d etachへ
作業中はあなたのPuTTYを閉じてください。そして次回PuTTYタイプでログインしたとき
画面に再接続すると、プロセスがまだ画面上で実行されていることがわかります。画面を終了するには#exitと入力します。
詳細についてはman screen
を参照してください。
ほとんどのプロセスでは、この古いLinuxコマンドライントリックを使って擬似デーモン化することができます。
# ((mycommand &)&)
例えば:
# ((sleep 30 &)&)
# exit
それから新しいターミナルウィンドウを起動してください。
# ps aux | grep sleep
sleep 30
がまだ実行中であることを示します。
あなたがしたことは子の子としてプロセスを開始することです、そしてあなたが終了するとき、通常終了するプロセスを引き起こすであろうNohup
コマンドは孫の子にカスケードしないで、それでも孤立したプロセスとしてそれを残しますランニング。
私はこの "設定して忘れる"アプローチを好みます。Nohup
、screen
、tmux、I/Oリダイレクション、あるいはそのようなものを扱う必要はありません。
ログアウト時の引数として、Nohupは、親プロセスが強制終了された場合にクライアントプロセスが強制終了されないようにします。さらにもっと良い:
Nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null
Nohupを使用すると、SSHセッションとその子プロセスがログアウトしたときに強制終了されるプロセスが、終了しないようになります。私が与えたコマンドはあなたが後でそれを正しく殺してログアウトした後にプロセスを実行できるようにpidファイルにアプリケーションのpidを保存することができる方法を提供します。
Screenを使用してプロセスをrootとして実行する場合は、特権昇格攻撃の可能性に注意してください。自分のアカウントが何らかの形で侵害された場合は、サーバー全体を引き継ぐ直接的な方法があります。
このプロセスを定期的に実行する必要があり、サーバーに十分なアクセス権がある場合は、cronを使用してジョブを実行することをお勧めします。 init.d(スーパーデーモン)を使用してバックグラウンドでプロセスを起動することもできます。また、終了したらすぐに終了することもできます。
画面を使用してください。使い方はとても簡単で、端末用のvncのように動作します。 http://www.bangmoney.org/presentations/screen.html
この文字列をコマンドに追加してください:>& - 2>& - <& - &。 >& - 標準出力を閉じることを意味します。 2>& - 近い標準エラー出力を意味します。 <& - は標準入力を閉じます。 &はバックグラウンドで実行することを意味します。これはssh経由でプログラム的にジョブを開始するためにも機能します。
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
Xアプリケーションを実行したい場合は、 xpra を "screen"と一緒に使用してください。
オープンソースのlibslackパッケージの daemon コマンドもあります。
daemon
は、かなり設定変更が可能で、自動再起動、ロギング、pidfile処理などの面倒なデーモンに関するすべてのことを考慮しています。
私はまた、スクリーンプログラムに行くだろう(私はsome1他の答えがスクリーンだったことを知っているが、これは完成です)
&、ctrl + z bg disown、Nohupなどが、ログオフ時にジョブがまだ強制終了されるという厄介な驚きを与える可能性があるだけではありません。それは私がスクリーンを使用するように切り替えた原因であるが、私は二重フォークが解決するだろうとして私はanthonyrisinger解決策を推測します)、またスクリーンは単にバックグラウンドよりもメジャー利点があります:
screen will background your process without losing interactive control to it
ところで、これは私が最初の場所で尋ねることは決してないだろう質問です:) ...私はすべてのUNIXで何かをやっての私の最初からscreenを使用します...私は(ほとんど)決してscreenを起動せずにunix/linuxシェルで動作しません最初に...そして、私は今やめなければならないか、あるいは私は、良い画面が何であるか、そして何ができるかの無限のプレゼンテーションを始めます...それを自分で調べてください、それは価値があります;)
Systemd/Linuxでは、 systemd-run はセッションに依存しないプロセスを起動するための素晴らしいツールです。言いたい奴には言わせとけ
受け入れられた答えはNohupを使うことを提案します。 pm2 を使うことをお勧めします。 pm2 over Nohupを使うことには、アプリケーションの存続、アプリケーションのログファイルの維持、その他多くの機能など、多くの利点があります。詳細については これをチェックしてください 。
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
スクリーンコマンドを使いました。このリンクにはこれを行う方法についての詳細があります
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting