IO(docker)をブロックせずにstdinにデータがあるかどうかを確認するには?

IO(docker)をブロックせずにstdinにデータがあるかどうかを確認するには?

を実行するとecho this | docker run -i alpine cat取得しますthis
を実行するとstdinを読み取っdocker run -i alpine catたため、端末はブロックされますが、catそこには何もありません。

開いているファイル記述子を確認できます。を実行すると、docker run -i alpine ls -lA /proc/1/fd標準出力に次のように表示されます。

lr-x------    1 root     root            64 Aug  9 13:45 0 -> pipe:[10289389]
l-wx------    1 root     root            64 Aug  9 13:45 1 -> pipe:[10289390]
l-wx------    1 root     root            64 Aug  9 13:45 2 -> pipe:[10289391]
lr-x------    1 root     root            64 Aug  9 13:45 3

これは標準エラーです。

ls: /proc/1/fd/3: cannot read link: No such file or directory

すべてがecho this | docker run -i alpine ls -lA /proc/1/fd同じです(除くpipe:[these numbers])。

-iから削除しない場合は、docker runIOブロックなしでstdinにデータがあるかどうかを確認する方法はありますか?test -t 0stdin fdが常に開いているので、まったく機能しません。


stdinから読み込んでstdoutに出力するCLIコマンドを作成したいと思いますdocker run mycommand(stdoutは単純で興味深いものではありません)。だから、echo data | docker run mycommand入力データに基づいて他の内容を印刷したいと思います。ただし、これdocker run mycommandを行うには、「標準入力にデータを提供する必要があります」とマークする必要があります。

答え1

はい、読み取るデータがあるかどうかをシェルで確認できます。私はシェル入力の読み取りに関する多くの情報を保持しています。

https://antofthy.gitlab.io/info/shell/input_reading.txt

あなたの問題...「IOブロックを要求せずにstdinにデータがあるかどうかを確認する方法はありますか?」

基本的には「アンケート」(未読)テストが必要です。

read -r -t 0 var

これは実際には何も読みません。読み取る内容があれば終了状態は 0(true)、何もない場合は 1 を返し、EOF は false を返します。

また、これはデータが利用可能かどうかだけを示します。読み込みを試みるまで、入力が「ファイルの終わり」(EOF)にあるかどうかは通知されません。また、入力が完全な行(改行を含む)であるかどうかはわかりません。

ブロックせずに利用可能なデータを読み取るには...

  read -r -t 0.00001 line

ほとんどの場合、行全体を読み、通常は改行またはEOFが得られるまで入力をブロックすることに注意してください。改行文字が使用できない場合、上記のコードはエラー終了142と空白行を返します。これは、不完全な行の後にEOFが続く場合も同様です。

改行が利用可能であってもすべてのデータを読み取るには(すべての改行が含まれています)...

  while IFS= read -r -s -d '' -t .01 data
  do [ $? -ge 128 ] && break
    printf "$data"
  done

読みに-n1を追加すると、一度に1文字ずつ読みます!

何が欲しいのかを調べるには、上記のドキュメントのさまざまなセクションを読んでください。他のプログラミング言語の特徴と同様に、これらすべてがこの言語にも同様に適用されます。

追加

リストされたファイル記述子がシェルで読み書き可能な状態になっていることを確認できる「shell_select」という私が書いたPerlスクリプトをチェックしてください!

https://antofthy.gitlab.io/software/#shell_select

私はそれを使用して、入力を完全に独立して維持しながら、1つのファイルハンドルまたは別のファイルハンドルにぶら下がることなく(複数の)入力ストリーム(元の「bc」数学計算機のstdoutとstderr)を処理します。

関連情報