私はこのような単純なDockerfileを持っています
FROM ubuntu:latest
ADD run.sh /run.sh
CMD /run.sh
Run.shには、これがあります(これも非常に簡単です)
#!/bin/bash
Nohup awk 'BEGIN { while (c++<50) print "y" }' &
sleep 10
Bashからdockerでスクリプトを実行すると(つまり、対話モードでbashコマンドを実行し、そこでスクリプトを実行します)、スクリプトは正しく機能します。「Nohupモード」になり、出力はNohup.outに正しく表示されます。
ただし、/run.sh
デフォルトのコマンドとして、出力はまだSTDOUTにあります。
何が悪いのですか?なぜそれはdocker、bashで機能しますが、インタラクティブモードから実行された場合のみですか?
Nohup
は、コマンドがターミナルに送信される場合にのみ、コマンドの出力をリダイレクトします。出力が既に別のタイプのファイル(通常のファイルやパイプなど)に送信されている場合、Nohup
はこれが望ましいと想定し、Nohup.out
にリダイレクトしません。
デフォルトでは、docker run
はソケットを介してコマンドを実行します(ホストを仮想環境に接続します—これがホストの通信方法です)。ソケットはターミナルではないので、Nohup
はリダイレクトを実行しません。
docker run -t
を実行すると、Dockerはコンテナ内のターミナルをエミュレートするため、Nohup
はNohup.out
にリダイレクトします。コマンド名を渡さない場合、Dockerはdocker run -t bash
を使用したかのように動作します。
最善の解決策は、コマンドの出力を選択したログファイルに明示的にリダイレクトすることです。 stderrもリダイレクトすることを忘れないでください。そうすれば、彼らがどこに行くのかがわかるでしょう。
Nohup awk 'BEGIN { while (c++<50) print "y" }' >myscript.log 2>&1 &
私はDockerについてはあまり詳しくありませんが、コマンドの出力のリダイレクトに関しては Nohup
には内部的な魔法があります です。それは、自身の出力がポイントされている場所に応じて、さまざまな場所に送信します。
詳細については、リンクされた回答を参照してください。正確な回答はその間のどこかにあります Nohup
のPOSIX仕様 。