web-dev-qa-db-ja.com

ユーザー入力でスクリプトを実行してから、ジョブを切断してバックグラウンドで実行します

したがって、最初にユーザーに一連の3つの変数を要求するbashスクリプトがあります。次に、セッションから切断されたバックグラウンドでスクリプトを実行して、ラップトップとスーパーコンピューター間の接続を切断してもスクリプトが実行されるようにします。

変数は、次のようなコードでエコーを使用するように求められます。

echo "What is limit for low level optimization?" #ask for low limit
read low
echo "What is limit for high level optimization?" #ask for high limit
read high
echo "What method?" #ask for method
read input 

次に、長い一連のコマンドを実行します。

ただし、このジョブをセッションから正常に切断する方法がわかりません。前回、ログアウト後の手順で生成されたはずのファイルが作成されなかったため、「disown」コマンドが機能しませんでした。

私の理解では、Nohupはここでは機能しません。これは、スクリプトが最初に要求した入力を読み取ることができなくなるためです。

それで、これを設定する方法はありますか?

3
Pyrodancer123

スクリプトの2番目の部分でNohupが行うことをエミュレートすることで、これを実現できます。

Nohupコマンドは次のこと以上のことはしません。

  • スクリプトが端末の読み取りまたは書き込みを試行しないように、標準のファイル記述子をリダイレクトします。

  • SIGHUP信号をトラップし、無視します。 SIGHUPは、プロセスが制御端末を閉じたときに取得するものです。無視した場合、プロセスは端末が閉じられた後も実行を続けます。

次のスクリプトを使用してこれを実行できます。

echo "What is limit for low level optimization?" #ask for low limit
read low
echo "What is limit for high level optimization?" #ask for high limit
read high
echo "What method?" #ask for method
read input 
(
    trap '' 1  # Ignore SIGHUP
    # Series of long running commands
    # using $low, $high and $input
) </dev/null >myscript.log 2>&1 &

最後の行は、stdinを/ dev/nullから、stdoutとstderrの両方をmyscript.logにリダイレクトします(より適切なファイル名を選択し、タイムスタンプなどを使用して一意にすることができます)。

最後に、最後の&を使用してプロセス全体をバックグラウンドに置きます。

もう1つの可能性は、スクリプトを2つに分割し、2番目のスクリプトにlowhigh、およびinputをコマンドライン引数として、または場合によってはエクスポートされた環境変数として使用させることです。次に、actualNohupコマンドを使用して2番目の部分を実行します。これは、インタラクティブなプロンプトを処理しなくても2番目の部分の実行をスクリプト化できるという点で、より単純で、いくらか柔軟性があるはずです。

もう1つの可能性は、tmuxscreenなどのターミナルマルチプレクサを使用することです。これにより、切断された場合(または自分で切断した場合)にセッションに再接続でき、新しいセッションを開くこともできます。スクリプトが最初のウィンドウで実行され続けている間に新しいシェルを実行するためのウィンドウ。上記のソリューションのいずれかを実装するかどうかに関係なく、tmuxまたはscreenを採用することをお勧めします。可能であれば、試してみてください。

1
filbranden

長い一連のコマンドを中括弧で囲んでから、&を使用して待たずに続行できます。

echo "Read input"
{
    # all your commands in curly braces
    # ...
} & exit 0

その後、すべてのコマンドが終了するのを待たずに終了できます。サーバーから切断しても実行を継続する必要があります。

0
anderw