nohup と socat でリモート クライアント データをキャプチャできない

nohup と socat でリモート クライアント データをキャプチャできない

socatリモート サーバーで実行されている詳細出力とデバッグ出力をキャプチャする必要があります。

socatフォアグラウンドで実行すると上記を実現できます。

$ socat -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log

しかし、stdout.log上記がnohupバックグラウンドで実行された場合、出力は受信されません。:

$ nohup socat -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log &

stderr.log上記のバージョンを起動した直後は次のようになりますnohup socat

nohup: ignoring input
2024/03/24 20:06:22 socat[28360] I socat by Gerhard Rieger and contributors - see www.dest-unreach.org
2024/03/24 20:06:22 socat[28360] I This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)
2024/03/24 20:06:22 socat[28360] I This product includes software written by Tim Hudson ([email protected])
2024/03/24 20:06:22 socat[28360] I setting option "bind" to "0.0.0.0"
2024/03/24 20:06:22 socat[28360] I setting option "fork" to 1
2024/03/24 20:06:22 socat[28360] I setting option "so-reuseaddr" to 1
2024/03/24 20:06:22 socat[28360] I socket(2, 1, 6) -> 5
2024/03/24 20:06:22 socat[28360] W ioctl(5, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ...): Inappropriate ioctl for device
2024/03/24 20:06:22 socat[28360] I starting accept loop
2024/03/24 20:06:22 socat[28360] N listening on AF=2 0.0.0.0:8080

次に8080netcatからポートに接続します。

$ nc localhost 8080

そして、これがstderr.logcatpuresです。

2024/03/24 20:06:59 socat[28360] I accept(5, {2, AF=2 127.0.0.1:37910}, 16) -> 6
2024/03/24 20:06:59 socat[28360] N accepting connection from AF=2 127.0.0.1:37910 on AF=2 127.0.0.1:8080
2024/03/24 20:06:59 socat[28360] I permitting connection from AF=2 127.0.0.1:37910
2024/03/24 20:06:59 socat[28360] N forked off child process 28563
2024/03/24 20:06:59 socat[28360] I close(6)
2024/03/24 20:06:59 socat[28360] I still listening
2024/03/24 20:06:59 socat[28360] N listening on AF=2 0.0.0.0:8080
2024/03/24 20:06:59 socat[28563] I just born: child process 28563
2024/03/24 20:06:59 socat[28563] I close(4)
2024/03/24 20:06:59 socat[28563] I close(3)
2024/03/24 20:06:59 socat[28563] I just born: child process 28563
2024/03/24 20:06:59 socat[28563] I close(5)
2024/03/24 20:06:59 socat[28563] N reading from and writing to stdio
2024/03/24 20:06:59 socat[28563] I resolved and opened all sock addresses
2024/03/24 20:06:59 socat[28563] N starting data transfer loop with FDs [6,6] and [0,1]
2024/03/24 20:06:59 socat[28563] E read(0, 0x60485184f000, 8192): Bad file descriptor
2024/03/24 20:06:59 socat[28563] N exit(1)
2024/03/24 20:06:59 socat[28563] I shutdown(6, 2)
2024/03/24 20:06:59 socat[28360] N childdied(): handling signal 17
2024/03/24 20:06:59 socat[28360] I childdied(signum=17)
2024/03/24 20:06:59 socat[28360] I childdied(17): cannot identify child 28563
2024/03/24 20:06:59 socat[28360] I waitpid(): child 28563 exited with status 1
2024/03/24 20:06:59 socat[28360] I waitpid(-1, {}, WNOHANG): No child processes
2024/03/24 20:06:59 socat[28360] I childdied() finished

次に、netcat ターミナルにテキストを入力して、ENTER キーを押します。

しかし、問題は次のとおりです。netcatが終了するだけでなく、入力したテキストも表示されませstdout.log

ここで何が起こっているのかを明らかにすることに加えて、 の stderr と stdout をキャプチャする方法も教えていただけませんかnohup?基本的に、 のおよび出力と、リモート ソケット クライアントから に送信されたすべてのデータsocatをキャプチャする必要があります。-v-d -d -dstderr.logstdout.log

答え1

説明

のstdinについてですsocat

を使用してバックグラウンドで実行されるコマンドの場合&、基本的に 2 つの可能性があります。

  • シェルでジョブ制御が無効になっている場合 (スクリプトの場合はこれがデフォルト)、コマンドの stdin は (明示的なリダイレクトが実行される前に)/dev/nullまたは同等のファイルにリダイレクトされます。

  • シェルでジョブ制御が有効になっている場合(対話型使用ではこれがデフォルトです)、コマンドの標準入力は期待どおりなので、端末である可能性があります。端末の場合、バックグラウンドのコマンドはそこから入力を盗むことはできません。盗もうとすると、SIGTTINが取得されます。それでも、次のコマンドを使用してコマンドをフォアグラウンドに移動できますfgそれから端末から読み取ることができます。

nohup独自に標準ストリームを端末からリダイレクトするため、後者の場合でも、socatバックグラウンドまたはその子/スレッド/その他は、stdin から読み取ろうとするとすぐに EOF 状態 (または何らかのエラー) を取得します。

のようにデータをすばやく渡すことができるはずですがecho message | nc localhost 8080socatこの特定の接続を処理すると、stdin の EOF が原因で終了する前にメッセージが取得されるはずです。


解決

の標準入力の EOF が原因で接続が終了しないようにするにはsocat、ツールにこのアドレスから読み取らないように指示します。 からman 1 socat:

-u一方向モードを使用します。最初のアドレスは読み取り専用で、2 番目のアドレスは書き込み専用です […]。

-U逆方向に単方向モードを使用します。最初のアドレスは書き込みにのみ使用され、2 番目のアドレスは読み取りにのみ使用されます。

あなたの場合、-(つまりSTDIO)は2番目のアドレスなので、以下が必要です-u

nohup socat -u -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log &

関連情報