298

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

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

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

4

20 に答える 20

309

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

于 2008-11-12T19:21:30.157 に答える
169

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

于 2008-11-12T19:22:00.313 に答える
82

セッションが閉じられると、プロセスは明らかにキャッチしていない 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.
于 2008-11-12T19:27:26.307 に答える
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 として機能することがよくあります。

于 2012-03-10T12:01:44.263 に答える
37
nohup blah &

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

于 2008-11-12T19:31:35.660 に答える
17

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

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

これにより、バックグラウンドで処理され、結果がメールで送信されます。cron の一部です。

于 2008-11-12T19:53:57.970 に答える
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 を指定する必要があります)。ダブル ダッシュはどこでも機能するため、使用するのが最適です。

daemonize. _

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

于 2008-11-12T19:50:05.233 に答える
10

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

# ((mycommand &)&)

例えば:

# ((sleep 30 &)&)
# exit

次に、新しいターミナル ウィンドウを起動して、次の操作を行います。

# ps aux | grep sleep

sleep 30まだ実行中であることを示します。

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

nohup私はこの「設定して忘れる」アプローチを好みscreenます。

于 2016-07-03T00:59:11.907 に答える
7

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

sudo apt-get install tmux

使用法:

tmux

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

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

Ctrl+B の次に$

セット名

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

Ctrl+B の次にD

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

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

tmux アタッチ セッション名

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

于 2014-04-25T23:30:46.767 に答える
5

Nohup では、ログアウト時の引数として、親プロセスが強制終了された場合にクライアント プロセスを強制終了できません。さらに良いのは、次を使用することです。

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

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

于 2008-11-12T19:35:15.747 に答える
5

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

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

于 2008-11-12T19:53:08.580 に答える
3

スクリーンを使用します。使い方は非常に簡単で、端末の vnc のように機能します。 http://www.bangmoney.org/presentations/screen.html

于 2008-11-12T19:23:01.700 に答える
2

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

&、ctrl + z bg disown、nohupなどの事実だけでなく、ログオフしてもジョブが強制終了されるという厄介な驚きを与える可能性があります(理由はわかりませんが、それは私に起こりました、そしてそれは気になりませんでしたそれで私はスクリーンを使うように切り替えました、しかし私はダブルフォークがそれを解決するのでアンソニーリシンガーソリューションを推測します)、またスクリーンはただのバックグラウンドよりも大きな利点があります:

screen will background your process without losing interactive control to it

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

于 2012-05-30T09:23:05.840 に答える
2

X アプリケーションも実行したい場合は、xpraを「screen」と一緒に使用してください。

于 2011-11-15T00:17:53.500 に答える
2

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

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

于 2012-06-16T16:13:26.003 に答える
2

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

$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
于 2013-08-14T15:51:50.590 に答える