• ベストアンサー

パイプ

C++からはじめたので、パイプについてよくわかりません。 DOSで dir | more とか、UNIXで ls | more とかやると、前のコマンドの標準出力を、後ろのコマンドの標準入力に渡すというのは、わかるんですが、これはDOS上、UNIX上でのことですよね。 プログラムToプログラムで、パイプを使うには、どうしたらよいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.4

Windowsのパイプって名前つきパイプですよね。 多少“うろ覚え”が入ってますが、参考になれば…。 まず、「名前つきパイプはNT系のみのサポート」という前提があります。 9x系では使えませんので御注意下さい。 また、名前つきパイプを実現するのはAPI呼び出しの組み合わせです。 VBからでも、C++からでも、その組み合わせ(片方がVBで他方がC++)でも可能です。 Windowsの名前つきパイプはUnixのそれとは異なり、サーバーとクライアントという位置付けで構成されます。 サーバーはCreateNamedPipeで名前つきパイプを作成します。 作成された名前つきパイプに対するアクセスは(指定によって)サーバー→クライアント、サーバー←クライアント、サーバー←→クライアントのいずれかのアクセスが可能となります。 名前つきパイプはサーバー/クライアント双方でCreateFileすれば通常ファイルと同様にReadFile、WriteFileが可能です。 概念的には「サーバーが用意した“名前つきパイプオブジェクト”を仮想ファイルとしてI/Oし通信を実現する」という感じです。 MSDNライブラリでpipe、named pipe、CreateNamedPipe、CreateFileを調べてみてください。

haporun
質問者

お礼

\\.\pipe\pipename というファイルを出力側が用意し、受け取り側がそのファイルを開いて読み取るということになるのでしょうか。 うーむ、でもNT系にしか対応していないんですよね。 ソケットを使うといいのでしょうか。 ソケットもよくわからないのですが・・・。 何か、普通のコマンドライン引数のように、互いのプログラムが何か固有の値を知っていなければ、情報を交換できないようなもの、でないような、アプリケーション通信手段はないでしょうか。 名前とかIPとかが必要ないような。 相互通信である必要はありません。

その他の回答 (3)

  • honiyon
  • ベストアンサー率37% (331/872)
回答No.3

こんにちは、honiyonです。  http://www.google.com/search?q=CreateFile+%83p%83C%83v&hl=ja&lr=  上記「CreateFile パイプ」での検索結果です。  ちょっと時間がないので詳しくは調べてないのですが、軽く見た感じそれの文献がヒットしているようです。  VC++で作ったAPIをVBで使用したいというのは、VC++で作った関数を VBで使いたいと解釈して宜しいですか? それでしたらパイプとはまた違った事になると思います。  VC++で作った関数をDLL化し、VBからその関数をロードする、という方が適切かと思います。   参考になれば幸いです(..

haporun
質問者

お礼

MSDNライブラリは見たのですが、パイプに対する知識があまりないので、これを見ただけではわかりませんでした。 具体的にやりたいことは、アプリケーションが渡す引数の変わりに、パイプを使いたいと思ったのです。 コマンドライン引数は文字制限があるので。 パイプ付きでアプリケーションを実行し、VB用にCommand$関数のようなものを作って・・・。

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.2

DOSのパイプはリダイレクトを拡張したもので、前段プロセスがファイルに吐き出した標準出力を後段プロセスが標準入力とします。 結果、前段プロセスの終了をまって後段プロセスが起動します。 これはシングルタスクであるDOSの宿命です。 UNIX(Linuxを含む)のパイプは名前つき、名前なしの2種類があり、shellコマンドで実行可能な|は名前なしパイプです。 UNIXはマルチタスクなので前段プロセスと後段プロセスは同時に実行され、バッファリング単位(標準入出力ではBUFSIZまたは'\n'まで)ごとにデータが流れます。 UNIXを例にとります。 (DOSでも同様なライブラリ関数が用意されますが、上記の理由で動作は全く違います。また、細かな仕様も違うので確認して下さい) <親プロセスが前段、後段プロセスを起動する場合> Shellのやっている事と同じです。 1.親プロセスでpipe(2)システムコールを呼び出してパイプを作成 2.fork(2)システムコールで前段プロセスを生成 3.前段プロセスの標準出力をclose(2) 4.前段プロセスでパイプ出力側をdup(2)して標準出力とする 5.後段プロセスをfork(2) 6.後段プロセスで標準入力をclose(2) 7.後段プロセスでパイプ入力側をdup(2)して標準入力とする 8.前段、後段プロセスをexec(2) 前段/後段プロセスに当たるプログラムでパイプを意識したプログラミングがなされている場合、標準入出力のclose(2)とdup(2)は不要です。 名前つきパイプも使えます。 <子プロセスからの出力を受け取る場合> 1.pipe(2)でパイプを生成する 2.fork(2)で子プロセスを生成する 3.子プロセスで標準出力をclose(2) 4.子プロセスでパイプの出力側をdup(2) 5.子プロセスを目的のプログラムにexec(2) この手順を単純化したライブラリ関数がpopen(3)です。 子プロセスに当たるプログラムがパイプを意識したプログラムの場合、標準出力のclose(2)とdup(2)は必要ありません。 詳しくはman(1)コマンドで各システムコールを調べてください。 ()の中の数字はマニュアルの章番号でmanコマンドの第2パラメータです。 man 2 pipe のように使ってください。 以上の説明は、4.3BSD,SystemV Rel3.1以降の全てのUNIX(Linux含む)で通用するはずです。 老婆心ながら… UNIXならプロセス間通信にパイプを使うのは推奨されません。 プロセス間通信はメッセージまたはUNIXドメインソケット()を使います。

haporun
質問者

補足

書き損じました、すみません。 目的のプラットフォームはWinなのです。 ・・・でも、Win上でもpopenはあるようですね。 Winプログラムでは正しく動作しないようですが。 popenは呼び出したプロセスからの出力を受け取るようですが、呼び出したプロセスに出力を与えるという動作はできないのでしょうか。 APIのCreateFileがパイプを作れるようですが、どのように扱えばいいのかわかりません。 このハンドルはCのpipe関数の返すものと方が違うようです。

  • honiyon
  • ベストアンサー率37% (331/872)
回答No.1

こんにちは、honiyonです。  Linuxであれば、 popenを使うとプログラム同士でファイル入出力間隔で通信が出来ます。  popenで、「ls」を開いてあげると、lsを実行した結果をもらえる、といった感じです。  

haporun
質問者

補足

Win上ではムリでしょうかね。 具体的にはC++でAPIを作って、VBに使わせるということをしたいのですが。

関連するQ&A

  • シェルのリダイレクトとパイプについて

    シェルのリダイレクトとパイプについての質問です. リダイレクトでコマンドの標準出力をファイルに指定した後に, パイプを置いて,もう一つコマンドを並べたとき, 後の方のコマンドの標準入力はどうなるのでしょうか? 例えば, ls >outfile |cat ならば, catの標準入力には,何も入ってこないと思うのですが, これを実行すると,lsの結果がoutfileに書き込まれ, 次のプロンプトが表示されます. 普通,catを引数なしで実行すると, EOFが入力されるまで,入力待ちになると思うのですが, こうならないのは,シェルがcatの標準入力にEOFを入力したからだと 考えていいのでしょうか. よろしくお願いします. (質問の意味が分かりにくければご指摘下さい.)

  • パイプの使いかたについて

    linux初心者です。 パイプの使いかたについて教えて下さい。 パイプを使うことでパイプ前の結果をパイプ後に引きわたし、パイプ後にあるコマンドを実行できる、というようなことはネットで調べました。 ls -l | lessのような。。(ls結果をlessで表示する。) ここで質問なのですが、 grep photo | illust sample.txt としたとき、sample.txtのなかからphotoまたはillustに、マッチする行を抽出するという意味でよいのでしょうか? 自分で検証した限りではそのようにみえました。 ただ、そうだとしたとき、パイプの意味がよくわからなくなってしまいます。 パイプ前でコマンドを実行、その結果を引数にしてパイプ後でコマンドを実行するというように考えないほうがよいのでしょうか? すみませんが、使用方法について教えてください。

  • Mac ターミナルのコマンド、パイプの使い方

    Mac OS10.6.8 ターミナル2.1.2 を使用しています。 パイプの使い方で困っています。 command1 | command2 command1は標準出力に複数行の文字列を出力します。(例えばcd, ls) command2でパイプを通してcommand1の出力した文字列からワイルドカードに一致する文字列を含む行を標準出力に表示させたいのですが、そのようなコマンドが分からず困っています。 最近このような使い方をしたいことが多々あり、毎回目視で探すかファイルに出力し、 エディタで検索しています。 基礎的なことかとは思いますがよろしくお願いいたします。

  • teeコマンドを使わずにUNIXで標準出力とエラー出力を、ファイルと標準出力の両方に出すには?

    UNIX系のBシェルで、 コマンドを実行して、 その標準出力とエラー出力をログファイルに出力し、 かつ、同じものを標準出力にも出力したいのです。 また、その後でコマンドの戻り値$?をエラーチェックしたいです。 このため、パイプでteeコマンドを使用すると戻り値が上書きされてしまいます。 いったん一時ファイルに出力するしかないのでしょうか?

  • moreが使えない

    c:\windows\commandにあるmoreコマンドが使えないのです. DOSプロンプトで自作のプログラムを実行して結果を表示させるのですが,表示される項目が多いので前の画面を見たいのです. そこで コマンド | more と入力します. すると前のコマンドは実行され,次に「コマンドまたはファイルが見つかりません」と表示されます. (more実行されません) それで同じようにc:\windows\commandにあるものも使えないようなのです. この場合どうすればmoreなどが使えるようになるのでしょうか? OSはwindows98SEです.

  • 標準入出力 パイプ

    Dosコマンド: dir | output.pl が動かない理由を教えてください。 Perlやパスなどの環境は動く環境になっています。 output.pl▼ http://msugai.fc2web.com/perl/output.html #希望する動作、dirの出力をファイルに格納

    • ベストアンサー
    • Perl
  • UNIX環境でFORTRAN書式なしデータをパイプで連結したい

    UNIX環境下で書式なしデータファイルを入力とするFORTRANプログラム を作成しています。このプログラムにパイプを使用して上記の書式なし データを渡したいのですが、現在うまくいきません。パイプに渡す外部 のコマンドとしては解凍プログラム(gunzip)を使用しています。 パイプを使用してFORTRANプログラムに書式なしデータを渡す方法があれ ばお教えください。

  • ホームページでDOSコマンド練習機能は実現可能でしょうか? 

    簡単なDOSコマンド練習用WEBを作りたいと思っています。 実現したい内容は以下のようなイメージです。 ホームページにアクセスすると、ホームページ内にDOS窓みたいなウインドウがあり(格好悪いけど、フォームでも可能)、そのウインドウ内に『c:\』とかプロンプトが出ていて、そこで『dir』と入力してリターンを押すと、本物じゃなくて構わないので、あらかじめ用意されていたdirに対応する出力が、だらだらと表示される仕組み。 コマンド入れずにリターンの連打をするとDOS窓同様にプロンプト『c:\』が繰り返し表示されるイメージです。 完全なエミュレーターではなくて、DOSコマンド数種類だけを試す ようなWEBを作りたいと思っています。 お知恵お貸しくださいませ。 Take

  • C++ で DIR コマンド

    MS-DOSプロンプトで dir と入力すれば、フォルダ内の 様子がMS-DOSプロンプトに表示されるけど、 C++ で、MS-DOSプロンプトで dir と入力したのと同じ 様にするにはどういうプログラムを作ればいいのですか? 別の言い方で書くと、実行すればMS-DOSプロンプトが 起動し、dir と入力されて dirコマンドが実行される というファイルを作るソースが知りたいんです。 dirコマンドが実行される対象となるディレクトリは どこでもいいんです。 C++ のプログラムでも、ディレクトリ構造を出力することが 出来ると思うんだけど、MS-DOSプロンプトでやってみたいんです。 どうしてそんなことがしたいのかというと、C++ が難しそうだから という理由なんです。 例えば、ファイルコピーを自動化するプログラムを作る時、 C++ のプログラムの出力をMS-DOSプロンプトへ渡す方法を知っていれば、 MS-DOSプロンプトでのコピーは copy コピー元 コピー先 という簡単な書式だから、ファイルコピーを自動化するプログラムも 簡単に作れそうだなと思ったんです。

  • findの結果をlsで詳細表示

    はじめまして。 Linux初心者です。 カレントディレクトリ以下のディレクトリやファイルの一覧を詳細表示するには「find ./ | xargs ls -lF」などとすると思いますが xargsを使用せずに「find ./ | ls -lF」とすると、なぜNGなのでしょうか。「xargs」の意味を調べると、 (1) 標準入力から空白か改行で区切られた文字列群を読み込む。 (2) xargsの引数のコマンドの後ろに、標準入力から受け取った文字列群を付け足して、そのコマンドを実行する。 とありました。上記の説明で「xargs」を付けることによる効果はわかるのですが、ls以外のコマンドを使用する際にもfindと組み合わせる際には、 すべてのコマンドで「xargs」を使用しなければいけないのでしょうか。 lsの結果をmoreする際などには、「ls | more」で良いと思うのですが、 「ls | xargs more」としない理由がわかりません。 どなたかわかりやすく教えて頂ければ幸いです。 よろしくお願いします。

専門家に質問してみよう