fabfileを使用して、リモートボックスでプログラムをリモートで起動し、結果を取得する必要があります。プログラムの終了には時間がかかるので、バックグラウンドで実行したいので、待つ必要はありません。そこで、os.fork()を試して動作させました。問題は、リモートボックスにSSHで接続し、そこでos.fork()を使用してプログラムを実行すると、プログラムはバックグラウンドで正常に動作することですが、fabfileのrunを使用しようとすると、sudoを使用してプログラムをリモートで起動します。 fork()は機能せず、プログラムはただ静かに終了します。そこで、プログラムをデーモン化するためにPythonデーモンに切り替えました。長い間、それは完璧に機能しました。しかし、Pythonシェルフの辞書を読み取るようにプログラムを作成し始めたとき、python-daemonは機能しなくなりました。python-daemonを使用している場合、シェルフdictを正しくロードできないようですが、その理由はわかりません。
2 に答える
私があなたの質問を正しく理解しているなら、あなたはこれをあまりにも複雑にしていると思います。 os.fork()
マルチプロセッシング用であり、バックグラウンドでプログラムを実行するためのものではありません。
議論のために、program.sh
標準出力に送信するものを実行して収集したいとします。ファブリックでこれを行うには、ローカルで作成します。
fabfile.py:
from fabric.api import run
def runmyprogram():
run('./program.sh > output 2> /dev/null < /dev/null &')
次に、ローカルで次を実行します。
fab -H remotebox runmyprogram
プログラムはリモートで実行されますが、ファブリックはプログラムの終了を待機しません。おそらくscpを使用して、後で出力ファイルを収集する必要があります。「&」はこれをリモートマシンのバックグラウンドで実行し、ファブリックセッションのハングを回避するために出力リダイレクトが必要です。
ファブリックを使用する必要がない場合は、これを行う簡単な方法があります。個別にsshして実行できます
nohup ./program.sh > output &
その後、後で戻って出力を確認します。
これを定期的に実行する場合は、cronジョブを設定して頻繁に実行し、必要なときにいつでも出力を収集できるため、これがより適切なオプションになる可能性があります。
後で出力ファイルを収集したくない場合は、次を使用できます。
fabfile.py:
from fabric.api import run
def runmyprogram():
run('./program.sh')
次に、ローカルマシンで:
fab -H remotebox runmyprogram > output &
ジョブはリモートで実行され、すべての出力をローカル出力ファイルに戻します。これはローカルマシンのバックグラウンドで実行されるため、他のことを行うことができます。ただし、ローカルマシンとリモートマシン間の接続が中断される可能性がある場合は、最初のアプローチを使用して、出力が常にリモートマシンに安全に保存されるようにすることをお勧めします。
将来この投稿に出くわした人のために。Pythonデーモンは引き続き機能します。同じプロセス内でシェルフディクテーションをロードすることを忘れないでください。そのため、以前はシェルフdictが親プロセスにロードされていましたが、python-daemonが子プロセスを生成すると、dictハンドラーが正しく渡されません。これを修正すると、すべてが再び機能します。
このスレッドに関する貴重なコメントを提案してくれてありがとう!