stdinの内容を見る

stdinの内容を見る

stdinを介してコマンドを受け取るLinuxアプリケーションをデバッグしようとしていますが、stdinに記録されているすべてのものを見ることができれば非常に便利です。

私の最初のアプローチはを実行することでしたが、私のプロセスとプロセスは両方ともそのファイル記述子の内容を消費しようとしましたが、1つのプロセスだけが競争に勝つことができたsudo cat /proc/$pid/fd/0ため、これは非効率的なアプローチであることが証明されました。cat

別の方法はtailを使用することですが、次の理由で機能しません。ここ

アプリケーションにデバッグログを簡単に追加すると、問題が解決します。しかし、私が見逃したより一般的なアプローチがあるかどうかを知りたいです。

答え1

strace

以下の例stdinを読み込み、/tmp/foofileに書き込むcatプロセスを起動します。 pidを見つけて追跡します。元の猫ウィンドウにHey、Come onというテキストを入力します。

# cat >/tmp/foofile


# ps -ef|grep cat
steve     2134  1801  0 22:25 pts/2    00:00:00 cat
# strace -fp 2134
Process 2134 attached
read(0, "test\n", 65536)                = 5
write(1, "test\n", 5)                   = 5
read(0,

ファイル記述子0から読むには:

strace -fp 2134 -e trace=read -o "|grep read.0,"

答え2

Linuxでは、アプリケーションのファイル記述子を/dev/fd/[0-9]teeそして標準出力として。それでは、私はあなたの状況に遭遇したときに何をしますか?(いつものように)私の読書アプリケーションですtee- stderrへの入力です/dev/fd/2

このように:

seq 10 | tee /dev/fd/2 | wc -c
1
2
3
4
5
6
7
8
9
10
21

もちろん、Linuxシステムを使用していなくても、移植によって同じことを行うことができます。場合によってはあまり具体的でない場合は、次のようにします。...| tee /dev/tty | ...

ターミナルの話ならstdin (リンクに示すように)カーネルのラインバッファリングのため、この方法はより難しいかもしれませんが、おそらくまだ同じことをします。したがって、この場合、私がすることは、tty私のコマンドをラップしてすべてのI / Oを記録することですluit。どちらも便利だと思うので、scriptほぼ同じように機能することもできます。

luitおそらくシステムにすでにインストールされているでしょう。通常は一緒にパッケージ化されていますxterm。 UTF-8変換を実行するように設計された非常にシンプルなcliツールです。(cliスイッチを介して機能を完全に無効にすることは可能ですが、そうする理由が見つかりませんでした)それを理解していない端末アプリケーションの場合。

現在のtty階層の下に独自のpty(基本fdを所有)を階層化し、現在のセッションのすべてのI / Oを要求されたアプリケーションを実行中の下位階層にコピーするように機能します。マスターを所有しているため、読み書きするすべてのI / Oを他の場所で簡単に複製でき、そうするように要求する便利な方法を提供します。

luit -olog /dev/fd/2 sh -c 'read var; echo "$var"'
eecchhoo  tthhiiss  vvaarr??????

echo this var???
echo this var???

ご覧のとおり、すべての端末入力は、受信するとluit名前付きファイルに書き込まれます。-olog

この場合、/dev/fd/2すべてのI / Oが同じ場所で2回発生するため、使用するのはあまり役に立ちません。私は通常、2番目の端末を開き、コマンドを使用して名前を照会ttyし、その名前を/の名前付き出力ファイル/dev/pts/[0-9]として使用することを好みます。これにより、すべてのI / Oが両方の端末に同時にコピーされるため、1つの端末から読み取ることができます。それを取るか、または見、反対側で相互に作用しなさい。ほとんどの場合、同じ操作を実行するために使用できますが、一般的には、ptyの主な面で推奨される利点はありません。luitscripttee

あなたの目的があなたのレビューのためにいくつかのプロセスにすべての入力をコピーすることであれば、入力に集中する方が良いでしょう。straceこれは多くの場合に便利ですが、一般的な動作に関する正確なレポートを取得するには、レポートを収集するときにその動作をできるだけ少なく変更する必要があります。つまり、入力が必要な場合は、入力をコピーしてデバッグ親プロセスを挿入しないでください。これにより、-TRAPシステムコールが行われるたびにプロセスが一時停止します。

答え3

1つの可能性(これが他の問題を中断しない場合)に呼び出しを挿入することです。tee。このコマンドはteeデータをコピーするので、1つのコピーはアプリケーションに送信され、1つはデバッグ出力に送信できます。電話をかけずにyour_application通話をスケジュールしますtee input.log | your_application。アプリケーションへの入力がファイルの場合、これは侵入的な変更ではなく、パイプではない場合、結果としてパイプになります(たとえば、パイプを取得できません)。

もう1つの可能性は、アプリケーションが実行するファイル読み取り操作を追跡することです。あなたはこれを行うことができますストレス:

strace -e read=0 -e trace=read -e signal=none your_application 2>&1 |
grep '^ |'

関連情報