
A 回答 (6件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
No.2 & 4 です。
---
(1)におけるstraceの実行結果を載せると
% strace cat filename | COMMAND
....
---
これだと cat を strace することになってしまいます。
% cat filename | strace COMMAND
としないといけません。
その時注目すべきは read(0,...) というようにファイル記述子の0番に対する操作です。
この回答への補足
まず、(1)と(2)でscriptを用いて出力をファイルにダンプし、それらをdiffしたところ、かなりの量の違いが出力されました。プロセスIDなど、変わってしかるべき以外の細かい点もあります。これは、詳しく見ないと分からないですね。
次に、お勧めのように
% grep "read(0," ダンプ結果
として、(1)と(2)それぞれでread(0,...を抜き出し、diffを取ったところ、全く差がありませんでした。従って、read(0,...という標準入力の読み取りに関する操作では、違いがないということが判明しました。
さらに、ダンプ結果において、(1)の方法ではエラーが出ている箇所を探し出してその周辺を比較しました。制限字数が足りないので次に出します。
No.5
- 回答日時:
>全く一緒ということでしょうか?違いは全くありませんか?
ファイルの先頭から末尾まで順に読む処理であれば大きな違いはありません。違うのはread()で一度に読むデータ量です。Cで言うとgetchar()やfgets()で読む限り違いは無いです。厳密には(1)はcatが読んで書く速さより速くCOMMANDが入力を読むならば違いが出ます(待ちが発生する)。
ファイルの先頭から末尾まで順に読む以外の処理、例えば一度最後まで読んだあと再度先頭から読み直すとかの処理をしているのならば、(2)は可能ですが、(1)では不可能です。
また、入力がファイルかパイプかを調べてそれにより異なる処理をしているのなら当然違いが出ます。
ありがとうございます。
seek動作のほかにも、時間も変わりえるんですね。
No.4のお勧めどおり、まずはこのソフトウエアがパイプのときにどうなるか、確認して見ます。
No.4
- 回答日時:
再度 No.2 です。
ひょっとしてこの市販ソフトは、入力に pipe を許していないのではないでしょうか?
もし COMMAND が標準入力がファイルであることを前提に、lseek() していたりすると、pipe に対する lseek() は許されていませんので、当然エラーになります。この場合、「EOF がどうのこうの」というエラーメッセージになることも十分考えられます(lseek() の errno をちゃんと見ていなかった場合)。
これを確かめるには strace をすればいいんですが。どうしても原因を知りたいのであれば、man strace を見てください。
この回答への補足
(1)におけるstraceの実行結果を載せると
% strace cat filename | COMMAND
....
read(3, "400 148.7900 148.9000\n 0.09077 -"..., 4096) = 4096
write(1, "400 148.7900 148.9000\n 0.09077 -"..., 4096) = 4096
read(3, "+0014 35.460 -47.5400 -47.1900 "..., 4096) = 3102
write(1, "+0014 35.460 -47.5400 -47.1900 "..., 3102) = 3102
read(3, "", 4096) = 0
brk(0) = 0x806e000
brk(0) = 0x806e000
brk(0x806d000) = 0x806d000
brk(0) = 0x806d000
close(3) = 0
close(1) = 0
exit_group(0) = ?
でした。exit_group(0)=?ってのがおかしいのかと思ったのですが、(2)における実行結果も、最後は同様にexit_group(0)=?で終わっています。これが原因ではないようですね。もう少し調べて見ます。
No.3
- 回答日時:
>例えば、ktermなどの端末上でcat自身にEOFを知らせるにはCTR-Dをしますが、それはcatがCTR-Dというシグナル(実体)を受け取って判断しているわけではないということですか。
はい。違います。Ctrl-Dを認識するのはttyドライバです。ttyドライバは行頭でctrl-Dを入れると長さゼロのデータをプログラムに送ります。
この長さゼロのデータをプログラムはEOFと判断します。
ファイルから入力の場合は、ある長さのデータを読むわけですが、データがなくなって、さらにもう一度読むと、「長さがゼロのデータ」が読まれます。この長さゼロのデータをプログラムはEOFと判断します。端末の場合とプログラムの動きは同じです。
>COMMAND内にてファイル終端を判断させているのですが
具体的にどうやって終端を判断させているのですか?そこに間違いがあるのではないでしょうか?
この回答への補足
ありがとうございます。そうすると、
(1) % cat filename | COMMAND
(2) % COMMAND < filename
は全く一緒ということでしょうか?違いは全くありませんか?
このCOMMANDは、ある既成のソフトウエアなのですが、標準入力からのEOFを判断するようになっています。(1)では標準入力からのEOFを認識できずに読み込みエラーとなり、(2)ではEOFをちゃんと認識しています。
(1)と(2)で全く差がないのであれば、このCOMANNDが(1)と(2)とで動作が異なるような処理をしていることになるのでしょうね。もはやベンダーに尋ねるしかないかもしれないですね。
No.2
- 回答日時:
fgetc() など FILE 操作の関数は EOF を返すので、EOF という実体があるような気がしても不思議ではないです。
が、実際には EOF という実体はなく、状態があるだけです。pipe の場合は、送る方の端を close() すると受け取り側で EOF になりますし、ファイルの場合はファイルの最後まで読めば(あるいはシークポインタがファイルの最後を指していれば)EOF になります。cat はファイルを読み込んでは標準出力に出力し、EOF になったら終了します。この時出力がパイプで他のプログラムにつながっていた場合は、パイプの端が close() され、それが次のプログラムに伝わることになります。
ということでシェルのパイプでつなごうが、リダイレクトしようが EOF に関しては同じ結果になるハズです。
ただし、
% COMMAND | HOGEHOE
とやって、HOGEHOGE が EOF の前に終了してしまった、つまり pipe の入力端が close() されてしまった状態で、なおかつ出力しようとした場合、COMMAND には SIGPIPE シグナルが発生し、異常終了となります。これは man ページを見ていて途中で終了したりすると Broken pipe というメッセージがでるのと同じ現象です。
この回答への補足
ありがとうございます。
例えば、ktermなどの端末上でcat自身にEOFを知らせるにはCTR-Dをしますが、それはcatがCTR-Dというシグナル(実体)を受け取って判断しているわけではないということですか。
catはEOFを受け取ると終了、という説明を見かけた為、ファイルのEOFを受け取ると、EOFは出力せずに終了するのかと解釈していました。
ただ、現にパイプとリダイレクトで結果が異なるので、そうするとこのコマンドの内部処理の問題ということなのでしょうか・・・・
catやawkでパイプの端をclose()するような出力は、できない(存在しない)ということでしょうか。
No.1
- 回答日時:
EOFの扱いに違いは無いと思います。
>% cat filename | COMMAND ...(1)
catの標準出力が、COMMANDの標準入力に接続される。
>% COMMAND < filename ...(2)
COMMANDの標準入力にfilenameの内容が送られる。
違いといえば、(2)と比べて、(1)は「cat」コマンドが余計に
起動するのでその分余計なリソースを使うという点でしょうか?
この回答への補足
ありがとうございます。
COMMAND内にてファイル終端を判断させているのですが、(1)ではファイル終端を見つけられずにエラーとなり、(2)ではファイル終端を見つけて正常終了となります。そのため、このような違いがあるのかと思いました。
確か、catはファイル終端を見つけるまで標準出力させるはずですが、そのためにファイル終端自身を標準出力していないのではないかと疑念を持ったわけです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- その他(プログラミング・Web制作) bashのgrepで複数の検索、かつスクリプト内で改行する方法を教えてください。 1 2022/10/06 20:09
- UNIX・Linux 実行の仕方及び実行結果が分かりません。 2 2022/11/17 19:31
- Excel(エクセル) Excel VBAどこが間違ってますか? 4 2023/07/17 10:04
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- 英語 英語のUSEとcommandの意味の違いはなんですか? 1 2023/07/07 10:48
- Visual Basic(VBA) エクセルの数式で教えてください。 1 2023/07/31 15:49
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- Visual Basic(VBA) 【VBA】写真の縦横比を変えずに貼り付ける 5 2023/06/13 11:42
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ファイルに書き換えるように出...
-
動画ファイルのサイズ変更
-
VOB→RMについて
-
C++での検索と出力について
-
UNIX & Linux の標準出力で得た...
-
eclipseで作成したプログラムの...
-
半年以上前のファイルの時刻表示
-
CSVファイルを任意の場所に出力...
-
VB6でなにか出題を・・・・
-
ワークステーション上の画面の...
-
C言語にてテキストファイル内の...
-
入力した値をファイルに出力す...
-
fortranのtxtファイル出力書式...
-
VBでFORTRANの制御ができない
-
MS-Word で作成した表をLatexに...
-
raw形式からbmp形式への書き込...
-
C言語でファイルからの文字列抽...
-
パイプラインとリダイレクトの違い
-
JISコードでファイル出力したい。
-
Turbo Delphi での、unicode 出...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コマンド(例えばls)の出力結果...
-
【ExcelVBA】UTF-8(BOM無)でC...
-
ファイル出力の場所を指定
-
VC++でUTF-8のファイルを出力し...
-
ファイルの文字コードをUTF-8に...
-
シェルコマンドの 2>&1 とはど...
-
Acccess レポートをグループ別...
-
BitBltについて。
-
Wordマクロで指定したフォルダ...
-
ファイル形式またはファイル拡...
-
CSV形式に変換
-
テキストファイルに改行コード...
-
C++ fprintf_sの使い方がわからん
-
外国語とCSVについて
-
1行ずつではなくまとめてファイ...
-
pcap形式データをテキストへ抽出
-
重複チェックプログラム
-
AviUtlでAVI出力が途中までしか...
-
CBool関数について VB6とVB.net...
-
標準出力とファイルに効率的に...
おすすめ情報