この記事は1年以上前に投稿された記事で現在は正しい情報とは限りません。

名前付きパイプのFIFOに関する備忘録

コマンドで作成

パイプの簡単な動作確認

書き込み側

読み取り側

どちらが先でもOKで、両サイドでファイルをオープンした段階で処理が始まります(ブロックする)

リモートポートフォワードで使う

任意のクライアントAがグローバルIPが割り振られていないホストBに対してSSHにログインしたい場合は、グローバルIPが割り当てられているホストC経由でポートフォワードすることにより、SSHログインすることが出来ます。

具体的には、グローバルIPが割り当てられているホストCで以下を実行して

ホストBで以下を実行

これで任意のクライアントAで以下を実行すると接続できます。

netcatはTCP通信したり、TCPサーバを立てれるコマンドになります。netcatの標準入力は接続先に渡され、接続先からのデータは標準出力に渡されます。

FIFOを使ったリモートフォワードの仕組みとしてはだいたいこんな感じ(説明がかなり冗長…)

  1. ホストBとホストCが接続される
  2. ホストAからホストCの接続用ポート対してSSHを実行(データを入力)
  3. 2の標準出力はホストCのB-C間接続しているnetcatの標準入力として渡される
  4. ホストBのB-C間接続しているnetcatの入力として渡される
  5. 4の標準出力はホストBのlocal sshしているnetcatの標準入力として渡される
  6. ホストBのlocal SSHのレスポンスが標準出力としてFIFOに渡される
  7. ホストBのFIFOに渡されたデータはB-C間接続しているnetcatの標準入力として渡される
  8. ホストCのB-C間接続しているnetcatにデータが渡され、ホストCのFIFOに標準出力として渡される
  9. ホストCのFIFOに渡されたデータはA-C間接続しているnetcatの標準入力として渡される
  10. ホストAにSSHのレスポンスが返る

ちなみに上記の方法だと一回で接続が切れてしまうので、実際に利用する場合はwhileループかけるのが良さそうです。

selectで試してみる

多重I/Oシステムコールのselectで試してみました

ここで注意しないといけないのが、デフォルトではFIFOのオープン時にもう一つの読み書きの口がオープンされるまでは処理がブロックされるということ。上記スクリプトを起動したときに、他のプロセスが対象FIFOに対して書き込みオープンしなければ、ブロック状態が解除されず処理が進みません。さらに上記例だと、複数のFIFOをオープンしているのでhoge1.fifo→hoge2.fifo→hoge3.fifoの順に書き込みオープンしないと先の処理にすすめません。(オープン後は正常に読取り処理が行われます)

以下のようにノンブロックでファイルをオープンすればブロックを回避できます。

Pythonの場合はopen関数の代わりにos.open関数を使ってos.O_NONBLOCKのフラグを立ててオープンすることになります。

参考URL