ユーザー入力を反映するシェルで実行されるプロセスがあるとします。それでは、他の端末からこのシェルにデータを渡すにはどうすればよいですか?中間ファイルを使用しないことは可能ですか?
たとえば、コードがあれば
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を準備する
リスナーを生成するために
program
w1でシェルスクリプトを作成しました。#!/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 プログラムは、読み取りが「停止」された場合にのみ書き込みます。