kronaemmanuel:
これは宿題の問題です。タスクは、コマンドを複製することです:ls | wc -l
使用してCプログラムではexeclp
、fork
とのパイプを。
私のアプローチ
私はこの問題は、この方法で解決することができると思います:
- パイプファイルを作成します。
pipe.txt
- 使用して子プロセスを作成します。
fork()
- マップ
stdout
に子プロセスのをpipe.txt
- 実行
ls
使用execlp
- これは、出力のを置く
ls
にpipe.txt
- マップ
- 親プロセスの内部
- マップ
stdin
に親プロセスのをpipe.txt
- 実行
wc -l
使用してexeclp
、それは代わりに標準入力から読み込むように、任意の更なる引数を与えることなく - 以来
stdout
、それは、端末上の行数をプリントアウトする必要がありますので、この親プロセスのは、まだ、端末そのものであります
- マップ
マイコード
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
int main() {
int pipefds[2];
int returnstatus;
int pid;
char argArr[30] = {'\n'};
returnstatus = pipe(pipefds);
if (returnstatus == -1) {
printf("Unable to create pipe\n");
return 1;
}
int file_desc = open("pipe.txt", O_RDWR | O_APPEND | O_CREAT);
pid = fork();
if (pid == 0) {
int copy_desc = dup2(file_desc, 1);
execlp("ls", "ls", NULL);
} else {
int copy_desc = dup2(file_desc, 0);
close(copy_desc);
execlp("wc", "wc", "-l", NULL);
}
return 0;
}
実際の出力
main.cpp blabla.cpp main pipe.txt
>
問題
これで間違っている二つのこと:
私はあることを子供の標準出力を設定しているので
pipe.txt
、ファイル、なぜそれが端末上で、まだ出力していますか?注:これは、出力を入れないpipe.txt
、あまりにもファイル。しかし、なぜそれはあまりにも、端末に表示されていますか?これは、ユーザーが入力を提供するために、待ちの状態になりますか?それは、パイプファイルの代わりに、ユーザからの入力を取得するべきではないでしょうか。
予想される出力
5
*現在のディレクトリ内の5つのファイルが存在する場合
試したソリューション
- ただパイプを使用した:(不正なファイルディスクリプタのエラーを得ました)
int main() {
int pipefds[2];
int returnstatus;
int pid;
returnstatus = pipe(pipefds);
if (returnstatus == -1) {
printf("Unable to create pipe\n");
return 1;
}
pid = fork();
if (pid == 0) {
dup2(pipefds[0], 1);
close(pipefds[1]);
execlp("ls", "ls", NULL);
} else {
dup2(pipefds[1], 0);
close(pipefds[0]);
execlp("wc", "wc", "-l", NULL);
}
return 0;
}
kronaemmanuel:
有益なコメントをありがとう。
コード内の問題は、私はすべてのパイプを使用していないということです。私は私が作成したファイルにすべての私の仕事をしていました。ように基本的な問題でした。
ここで、新しいコードは次のとおりです。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
int main() {
// Step1. Create pipe file descriptors: pipefd[0] for reading from pipe, pipefd[1] for writing to the pipe
int pipefds[2];
// Helping variables
int returnstatus;
int pid;
// Step2. Create a pipe with the file descriptors
returnstatus = pipe(pipefds);
// Check if pipe was successfully created
if (returnstatus == -1) {
printf("Unable to create pipe\n");
return 1;
}
// Step3. Fork to create a child process
pid = fork();
if (pid == 0) {
// Inside the child process
// Step4. Duplicate the file descriptor of the write end of the pipe and set it equal to the stdout of the process
dup2(pipefds[1], 1);
// Step5. Close both ends of the pipe
close(pipefds[0]);
close(pipefds[1]);
// Step6. Execute the LS command. It ouputs to stdout which we set equal to the pipe in Step4.
// So essentially, we send all output of ls to our pipe
returnstatus = execlp("ls", "ls", NULL);
// Error checking the execlp command
if (returnstatus == -1){
perror("Error executing execlp: ");
}
} else {
// Inside the parent process
// Step7. Duplicate the file descriptor the READ end of the pipe and set it equal to the stdin of the process
dup2(pipefds[0], 0);
// Step8. Close the both ends of the pipe
close(pipefds[0]);
close(pipefds[1]);
// Step9. Execute the WC command. It takes the file as an argument usually but if no file is given, it will take
// stdin as input. Since the stdin is the pipe, therefore it will read all the data from the pipe.
// The output of the wc command is stdout which is the terminal for this process so we will get the number of
// files/directories in the current directory as an output on the terminal
returnstatus = execlp("wc", "wc", "-l", NULL);
// Error checking the execlp command
if (returnstatus == -1){
perror("Error executing execlp: ");
}
}
return 0;
}