は、私は、配管やFDSをリダイレクトする原理を理解していました。しかし、パイプでの特定の動作が私の注目を集めています:パイプは、私は現在、C言語で自分の殻の実装を書いています
- cat | ls(またはstdinからパイプの最後の要素として読み取られないコマンド)。
その場合、シェルではlsが実行され、catは終了する前に(私が推測したSIGPIPEの結果で)1行を要求します。
char *cmd1[] = {"/bin/cat", NULL};
char *cmd2[] = {"/bin/ls", NULL};
int pdes[2];
pid_t child;
if (!(child = fork()))
{
pipe(pdes);
if (!fork())
{
close(pdes[0]);
dup2(pdes[1], STDOUT_FILENO);
/* cat command gets executed here */
execvp(cmd1[0], cmd1);
}
else
{
close(pdes[1]);
dup2(pdes[0], STDIN_FILENO);
/* ls command gets executed here */
execvp(cmd2[0], cmd2);
}
}
wait(NULL);
私が知っ:以下
http://web.cse.ohio-state.edu/~mamrak.1/CIS762/pipes_lab_notes.htmlは私が探しています振る舞いを再現しようとするために書かれているいくつかのコードです:私はより良い複数のパイプの原理を理解するために、このチュートリアルに従うことを試してみましたその実装のセキュリティ上の欠陥ですが、これはテスト用です。私はそれを理解するように、そのコードの問題は、LSが実行されますいつでも、それだけで終了し、その後、猫が何らかの形で、バックグラウンドで実行されることである(そして、それは私のプログラムが終了するなどのzshのプロンプト時に読み取ろうとするので、私の場合には失敗します)。私はそれがそうであるようにそれを働かせるための解決策を見つけることができません。コマンドを1つずつ待つと、そのようなコマンドはcat/dev/random |となります。誰もがこの問題の解決や、それが非常に高く評価されるだろう、少なくともいくつかのガイダンスを持っている場合はヘッド-c 10は...永遠
を実行します。ここ@thatotherguyからのコメントを考慮した後
私は全くコマンド有用性に興味を持っていないです。私はあるbashの動作を複製するにしか興味午前: 'cat'は'ながら孫になり、あなたの例では最初のlsの出力を表示し、(1ライン分のユーザを促しすなわち)1つだけの行を取る猫を実行している –
lsは子供です。 'wait'は' ls'を待つだけです。代わりに 'cat'と' ls'の両方の子を直接作成し、両方を待つべきです。 –
@thatotherguyはい確かに私はあなたのソリューションを実験しましたが、それは間違いなく機能します。そして、このソリューションは、私がリンクしているチュートリアルで提供されている最初のアイデアに近いようです。しかし、複数のコマンドでこれを拡張したい場合はどうなりますか?それが2番目の実装が私にとってもっと興味深いように見える理由です!私は多くの連鎖コマンドを持つことができるはずです。その解決策では、私はパイプやフォークを準備するためにどれだけのコマンドを事前に知っていなければならないようです。 –