中間ファイルを読み書きせずにシェル間でデータを渡す方法

中間ファイルを読み書きせずにシェル間でデータを渡す方法

ユーザー入力を反映するシェルで実行されるプロセスがあるとします。それでは、他の端末からこのシェルにデータを渡すにはどうすればよいですか?中間ファイルを使用しないことは可能ですか?

たとえば、コードがあれば

fgets(string, LEN, stdin);
printf("%s", string);

それでは、他のシェルにデータを渡し、別のシェルstdinからデータを取得することは可能ですか?stdout

答え1

しかし、どういう意味なのかよくわかりません。

単一のシェルセッション(ターミナル)内で、次のようにパイプを使用して、あるコマンドから別のコマンドにデータを渡すことができます。

$ ls -l | grep something

2つの異なるシェル間でこれを行う必要がある場合は、名前付きパイプを使用できます。

tty1$ mkfifo /tmp/mypipe
tty1$ ls -l > /tmp/mypipe
tty2$ grep something < /tmp/mypipe

mktemp名前付きパイプを配置するディレクトリを作成する方が安全です。

tty1$ dir=$(mktemp -d)
tty1$ mkfifo "$dir/mypipe"
tty1$ ls -l > "$dir/mypipe"
tty1$ rm -r "$dir"

これを行うには、パスを別のウィンドウにコピーする必要がありますが、おそらく手動です。

もちろん、名前付きパイプはパス名が必要であるという点で中間ファイルと少し似ています。しかし、データが永続ストレージに書き込まれず、ライターが遅い場合、リーダーは潜在的に早期にファイルが終了するのではなく、ライターを待つという点でパイプのように動作します。

ls -l *something*(代わりに通常を使用しますls | grepが、これは例として使用されます。)

答え2

@ilkkachuの答えが役に立ち、必要なものを提供すると思います。もっと詳しく説明しながら、同時にfifoの使い方も学んでみましょう。

  • 同じコンピュータに2つのコマンドラインウィンドウw1とw2を準備する

  • リスナーを生成するためにprogramw1でシェルスクリプトを作成しました。

    #!/bin/bash
    
    while true
    do
     read string
     if [ "${string:0:4}" == "Stop" ]
     then
      printf "Gotcha\n"
      break
     elif [ "$string" != "" ]
     then
      printf "$string "
     else
      sleep 3
     fi
    done
    
  • w1でfifoの準備

    dir=$(mktemp -d)
    mkfifo "$dir/mypipe"
    
  • プログラムを起動し、w1のfifoからの入力を待つようにします。

    < "$dir/mypipe" ./program
    
  • fifoを見つけて、w2からいくつかの文字列をエコーし​​ます。

    $ find /tmp -name mypipe 2>/dev/null
    /tmp/tmp.dRhpqajJqz/mypipe
    
    $ > '/tmp/tmp.dRhpqajJqz/mypipe' echo qwerty
    $ > '/tmp/tmp.dRhpqajJqz/mypipe' echo asdf
    $ > '/tmp/tmp.dRhpqajJqz/mypipe' echo Stopp
    
  • w1で出力を見る

    qwerty asdf Gotcha
    $ 
    

たとえば、次のように自動化することもできます。ここでは、名前が一時ファイルであると仮定しますmypipe

  • w1でプログラムを再起動してください。

    < "$dir/mypipe" ./program
    
  • w2から

    > $(find /tmp -name mypipe 2>/dev/null) echo 'Hello World'
    > $(find /tmp -name mypipe 2>/dev/null) echo 'Stop the World'
    
  • w1で出力を見る

    Hello World Gotcha
    $
    

デモCプログラム、

#include <stdio.h>
#include <string.h>

int main () {

 char string[21];
 while(1){
    fgets(string, 20, stdin);
    string[strlen(string)-1] = 0;
    if(strcmp("Stop", string) == 0){
        printf("Gotcha");
        return 1;
    }
 }
}

この C プログラムは、読み取りが「停止」された場合にのみ書き込みます。

関連情報