これはバックグラウンドで実行され、コマンドを待つループプログラムです。
#include <iostream>
using namespace std;
char buffer[256];
int main(int argc, char *argv[])
{
while(true){
fgets(buffer, 255, stdin);
buffer[255] = 0;
if(buffer[0] != '\0'){
cout << buffer;
buffer[0] = '\0';
}
}
return 0;
}
私はそれを実行します:
myLoop &
パイプを介してこのプロセスにコマンドを送信するにはどうすればよいですか?
答え1
私はこれが「実際の」パイプラインでは不可能だと思います。
man mkfifo
代わりに、FIFO(名前付きパイプ、参考資料を参照)、または(よりエレガントだがより複雑な)Unixソケット(AF_UNIX)を使用できます。
./background-proc </path/to/fifo &
cat >/path/to/fifo
# typing commands into cat
私は開発者ではないので、ソケットとの唯一の関係はですsocat
。しかし、始めるのに役立つかもしれません。
プログラムと通信するには「サーバー」が必要です。これらのパイプラインはバックグラウンドで始まります。
socat UNIX-LISTEN:/tmp/sockettest,fork STDOUT | sed 's/./&_/g'
これはsed
単なるテスト用です。
その後、1つ以上の開始
socat STDIN UNIX-CONNECT:/tmp/sockettest
バックグラウンドプログラム用のコマンドを生成するプログラムがある場合は、ここでもパイプを使用できます。
cmd_prog | socat STDIN UNIX-CONNECT:/tmp/sockettest
fork
FIFOに比べて利点は、(サーバー側のオプションを使用して)クライアントの接続を切断して再接続できることです。 FIFOでは、受信側を引き続き実行するにはいくつかのトリックが必要です。
while true; do cat /path/to/fifo; done | background_prog
答え2
バックグラウンドでコマンドを開始し、ファイル記述子にデータをパイプするようにしたい場合。
zsh
またはを使用すると、bash
リダイレクトを使用して交換を処理できます。
exec 3> >(cmd)
その後、出力を送信します。
echo something >&3
そして、ファイル文字の終わりを知らせるために使用しますexec 3>&-
。
続けてzsh
と を使用して、bash
次のこともできます。
{ coproc cmd >&3 3>&-; } >&3
これはcmd
、2つのパイプ(入力用パイプと出力用パイプ)でプロセスを開始するコプロセスで始まります。ただし、ここでは入力には1つだけが必要なので、残りのcmd
シェル出力に対してstdoutを標準に戻します。
出力を送信:
echo something >&p # with zsh
echo something >&"${COPROC[1]}" # with bash
渡すとyash
使えますプロセスリダイレクト:
exec 3>(cmd)
Bourneに似たシェルを使用すると、いつでも次のことができます。
{ {
echo something >&3
echo whatever
...
} 3>&1 >&4 4>&- | cmd; } 4>&1
cmd
これは、出力を送信するバックグラウンドでコマンドを開始して実行するのとまったく同じではありません。cmd
コマンドはサブシェルで実行され、対話型シェルの場合はcmd
前景でも実行されます(たとえば、Ctrl + Cの影響を受けます)。それよりも基本的に機能的に同じです。
答え3
通常、プロセスで開かれたファイルとプロセスが開始された後、プロセスの外部でそのファイルが指す場所を変更することはできません。インターフェイスとツールのデバッグには例外があります。レプティこれは限られた方法で行うことができます。
プログラムを起動すると
myLoop &
標準入力はすでにターミナルに接続されており(他の場所にリダイレクトしていないため)、パイプに変更されません。
また、見ることができます分離したプロセスに端末を接続するには?