「cat file | ./binary」と「./binary < file」の違いは何ですか?

「cat file | ./binary」と「./binary < file」の違いは何ですか?

変更できないバイナリファイルがありますが、次のようにできます。

./binary < file

私もできます:

./binary << EOF
> "line 1 of file"
> "line 2 of file"
...
> "last line of file"
> EOF

しかし、

cat file | ./binary

私にエラーが発生します。パイプではなぜ動作しないのかわかりません。 3つの場合、すべての内容は次のとおりです。文書割り当てられた標準入力バイナリ(他の方法を使用してください):

  1. bashはファイルを読み取り、それをstdinに供給します。バイナリ
  2. bashはstdinから(EOFまで)行を読み取り、それをstdinに供給します。バイナリ
  3. catはファイルラインを読み取り、それをstdoutに保存し、bashはそれをstdinにリダイレクトします。バイナリ

私が知っている限り、バイナリはこれら3つの違いに気付いてはいけません。 3番目のケースが機能しない理由を誰かが説明できますか?

ところで:与えられたエラーバイナリ例:

20170116/125624.689 - U3000011 スクリプトファイル "" を読み取れません。エラーコード「14」。

しかし、私の主な質問は違いは何ですか?すべてのプログラムこの3つのオプションがあります。

詳細は次のとおりです。もう一度試しました。ストレス 実際には少しエラーがありますESPIPE(違法追求)~から探す 続いてEFAULT(無効なアドレス)~から読むエラーメッセージの直前。

一時ファイルを使用せずにRubyスクリプトを使用して制御したいバイナリは次のとおりです。カラピ~から自動(UC4)

ベストアンサー1

存在する

./binary < file

binarystdin は読み取り専用モードで開かれたファイルです。ファイルはbashまったく読み取られず、実行中のプロセスのファイル記述子0(stdin)を読み取るためにファイルを開きますbinary

存在する:

./binary << EOF
test
EOF

シェルによっては、stdin は、シェルが入れた内容やパイプの読み込み先 ( ; ; とシェルがパイプの反対側に並列に書き込む) をbinary含む削除された一時ファイル (AT&T ksh、zsh、bash...) になります。 。あなたの場合。test\ndashyashtest\nbash

存在する:

cat file | ./binary

シェルに応じて、binarystdinはパイプの読み取り端または書き込み方向がオフになり(ksh93)、もうcat一方の端の内容が書き込まれるソケットペアの一方の端です。file

stdinが通常のファイル(一時または非一時)の場合は検索可能です。binary開始または終了に移動、巻き戻しなどが可能です。また、マッピングしてioctl()sFIEMAP / FIBMAPと同様の操作を実行できます(<>代わりに使用する場合は<切り取り/穴あけなど)。

一方、パイプとソケットのペアはプロセス間通信の手段であり、binaryデータ以外にできることはあまりありません(パイプ関連タスクなどの一部のタスクがありますが、通常のファイルではなくそのファイルに対して実行できます)。readioctl()

ほとんどの場合、seekパイプの使用時にアプリケーションが失敗/苦情を引き起こすのは、この機能が不足しているためです。ただし、通常のファイルでは機能しますが、他の種類のファイルでは機能しない他のシステムコール(たとえば、、、、、mmap()ftruncate()ですfallocate()。 Linuxでは、/dev/stdinfd 0がパイプや通常のファイルで開かれるときの動作にも大きな違いがあります。

処理できるコマンドがたくさんあります。閲覧可能これはファイルですが、この場合、通常は標準入力で開かれたファイルには適用されません。

$ unzip -l file.zip
Archive:  file.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       11  2016-12-21 14:43   file
---------                     -------
       11                     1 file
$ unzip -l <(cat file.zip)
     # more or less the same as cat file.zip | unzip -l /dev/stdin
Archive:  /proc/self/fd/11
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of /proc/self/fd/11 or
        /proc/self/fd/11.zip, and cannot find /proc/self/fd/11.ZIP, period.

unzipファイルの末尾に保存されているインデックスを読み、ファイル内のアーカイブメンバーを読む必要があります。ただし、ここではファイル(最初の場合は通常のファイル、2番目の場合はパイプ)がパス引数として提供され、呼び出し元が指定したunzipfdunzipを継承する代わりに、それ自体(通常は0ではないfdで)開きます。開けました。標準入力からzipファイルを読みません。 stdin は主にユーザーの対話に使用されます。

binaryリダイレクトせずにターミナルエミュレータで実行される対話型シェルのプロンプトでプログラムを実行すると、binarystdinは呼び出し側シェルから継承され、シェル自体は呼び出し側端末エミュレータから継承され、開かれたptyデバイスになります。読み取り+書き込みモード(同様のもの/dev/pts/n)。

これらのデバイスも検索できません。したがって、binary端末から入力を受け取るのがうまく機能している場合、問題はおそらく検索とは関係ありません。

14がerrno(失敗したシステムコールに設定されたエラーコード)の場合、ほとんどのシステムではこれEFAULT無効な住所)。read()書き込み不可能なメモリアドレスからの読み取りが必要な場合、システムコールはこのエラーによって失敗します。これは、fdが先のとがったパイプから読み取るのか、通常のファイルから読み取るのかとは何の関係もなく、通常Error 1を示します。

binary標準入力(を使用して)で開かれたファイルの種類を確認できます。fstat()通常のファイルでもttyデバイスでもない場合はエラーが発生します。

アプリについてもっと知らないと言うのは難しいです。これを(またはシステムでそれに対応するもの)実行すると、ここで失敗した場合にシステムコールが何であるかを理解するのに役立ちstraceます。trusstusc


想像したシナリオ1つマシュー・アイブあなたの質問についてのコメントはここで合理的に聞こえます。彼の言葉を引用するには:

データを読み取るためのバッファサイズを取得するためにファイルの終わりを見て、クエリが機能しないことを誤って処理し、負のサイズを割り当てようとするようです(間違ったmallocを処理しません)。与えられたバッファのどのエラーが無効かを読み取るためにバッファを渡します。

おすすめ記事