私はこれをするのに慣れています。
someprogram >output.file
私はプログラムで生成された出力をファイルに保存したいときはいつでもこれを行います。私もこれの2つのバリエーションを知っていますIOリダイレクト:
someprogram 2>output.of.stderr.file
(標準誤差の場合)someprogram &>output.stderr.and.stdout.file
(stdout + stderrの組み合わせの場合)
今日は不可能だと思った状況に直面しました。次のコマンドを使用すると、期待xinput test 10
どおりに次の結果が表示されます。
user@hostname:~$xinput テスト 10 ボタン30 リリースキー30 ボタン40 キーリリース40 ボタン32 キーリリース32 ボタン 65 キーリリース65 ボタン61 キーリリース61 ボタン 31 ^C ユーザー@ホスト名:~$
私はこの出力がいつものようにファイルに保存されることを期待しました。たとえば、.を使用しましたが、xinput test 10 > output.file
私の期待とは異なり、出力.ファイルファイルは空でした。これはまた、xinput test 10 &> output.file
stdoutやstderrで何かを見逃さないようにするためです。
本当に混乱しています。xinput
出力がリダイレクトされるのを防ぐ方法があるかどうか、ここでプログラムに問い合わせてみましょう。
修正する
ソースコードを見ました。このコードによって出力が生成されたようです(下記のコードスニペットを参照)。出力は通常のprintfによって生成されるようです。
//test.c ファイルから 静的無効 print_events(*dpy 表示) { XEventイベント; そして(1){ XNextEvent(dpy、&イベント); // [...いくつかの異なるイベントタイプがここにリストされています...] if((Event.type == key_press_type) || (Event.type == key_release_type)) { 整数ループ; XDeviceKeyEvent *key = (XDeviceKeyEvent *) &Event; printf("key %s %d ", (Event.type == key_release_type) ? "release" : "押された", key->keycode); for(loops=0;loopaxes_count;loop++){ printf("a[%d]=%d ", key->first_axis + loop, key->axis_data[loop]); } printf("\n"); } } }
stderrから出力コピーを取得できるように、ソースコードをこれ(以下の次のコードスニペットを参照)に変更しました。この出力をリダイレクトできます。
//test.c ファイルから 静的無効 print_events(*dpy 表示) { XEventイベント; そして(1){ XNextEvent(dpy、&イベント); // [...いくつかの異なるイベントタイプがここにリストされています...] if((Event.type == key_press_type) || (Event.type == key_release_type)) { 整数ループ; XDeviceKeyEvent *key = (XDeviceKeyEvent *) &Event; printf("key %s %d ", (Event.type == key_release_type) ? "release" : "押された", key->keycode); fprintf(stderr,"key %s %d ", (Event.type == key_release_type) ? "release" : "press ", key->keycode); for(loops=0;loopaxes_count;loop++){ printf("a[%d]=%d ", key->first_axis + loop, key->axis_data[loop]); } printf("\n"); } } }
現在の私の考えは、リダイレクトを実行すると、プログラムがメジャーリリースイベントを監視する機能を失う可能性があることです。
ベストアンサー1
stdout が端末でない場合にのみ出力がバッファリングされます。
を押すと、Ctrl-Cそのバッファがまだ書き込まれていないため失われます。
何でも使用すると同じ動作が得られますstdio
。たとえば、次のようになります。
grep . > file
空でない行を入力してキーを押すと、Ctrl-Cファイルが空であることがわかります。
一方、次のように入力します。
xinput test 10 > file
その後、キーボードで十分に入力してください。バッファー全体(最小4k出力)を取得すると表示できます。文書一度に4kずつ増加します。
を使用すると、forと入力してバッファをフラッシュして正常にシャットダウンgrep
できます。の場合にはそんなオプションがないと思います。Ctrl-Dgrep
xinput
バッファリングはstderr
デフォルトでは行われないので、他の動作が発生する理由を説明します。fprintf(stderr)
にxinput.c
1つを追加すると、つまり受信時に正常に終了するように指示するsignal(SIGINT, exit)
と、もはやnullではないことがわかります(信号ハンドラでライブラリ関数を呼び出すことが安全であると保証されないため、競合しないと仮定)。 printfがバッファに書き込むかどうかを検討してください。これは、信号が領域に入ると発生します。xinput
SIGINT
file
可能であれば、次のstdbuf
コマンドを使用してバッファリング動作を変更できますstdio
。
stdbuf -oL xinput test 10 > file
持つこのサイトに質問がたくさんあります。このオーバーライドは無効になります。標準入出力バッファリングを入力すると、より多くの代替ソリューションを見つけることができます。