C 在命名管道中存储Linux命令的输出
我的目标是获取用户输入的命令,并使用分叉子进程执行它,而不是让子进程将其打印到屏幕上,将输出存储在命名管道中,并让父进程在子进程完成后显示输出 我尝试使用dup2()将标准输出重定向到我制作的命名管道,但子进程只是打印命令的输出,当尝试在父进程中读取管道时,我得到以下错误: 读取管道时出错:错误的文件描述符 我在这个网站上搜索过类似的问题,但只找到了使用常规管道存储exec()输出的解决方案,我无法将这些解决方案应用于命名管道。这是我的密码:C 在命名管道中存储Linux命令的输出,c,fork,exec,named-pipes,C,Fork,Exec,Named Pipes,我的目标是获取用户输入的命令,并使用分叉子进程执行它,而不是让子进程将其打印到屏幕上,将输出存储在命名管道中,并让父进程在子进程完成后显示输出 我尝试使用dup2()将标准输出重定向到我制作的命名管道,但子进程只是打印命令的输出,当尝试在父进程中读取管道时,我得到以下错误: 读取管道时出错:错误的文件描述符 我在这个网站上搜索过类似的问题,但只找到了使用常规管道存储exec()输出的解决方案,我无法将这些解决方案应用于命名管道。这是我的密码: #include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define CMDSIZE 50
#define BUFSIZE 5000
int main() {
char cmd[CMDSIZE], arg[CMDSIZE], buf[BUFSIZE];
int fd, n;
pid_t pid = fork();
if (pid < 0) {
perror("Error creating process");
return 1;
}
else if (pid == 0) {
printf("SHELL > ");
fgets(buf, BUFSIZE, stdin);
sscanf(buf, "%s %s", cmd, arg);
memset(buf, 0, BUFSIZE);
printf("Working on request...\n");
unlink("cmdpipe");
mkfifo("cmdpipe", 0777);
fd = open("cmdpipe", 0777);
dup2(fd, STDOUT_FILENO);
close(fd);
if (arg[0] == '\0')
execlp(cmd, cmd, NULL);
else
execlp(cmd, cmd, arg, NULL);
}
else {
wait(NULL);
printf("...Output ready! Displaying now.\n");
fd = open("cmdpipe", 0777);
if ((n = read(fd, buf, BUFSIZE)) < 0) {
perror("Error reading from pipe");
return n;
}
close(fd);
printf("%s\n", buf);
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义CMDSIZE 50
#定义BUFSIZE 5000
int main(){
char cmd[CMDSIZE],arg[CMDSIZE],buf[BUFSIZE];
int-fd,n;
pid_t pid=fork();
if(pid<0){
perror(“错误创建过程”);
返回1;
}
否则如果(pid==0){
printf(“SHELL>”);
fgets(buf、BUFSIZE、stdin);
sscanf(buf,“%s%s”,命令,参数);
memset(buf,0,BUFSIZE);
printf(“根据请求工作…\n”);
取消链接(“cmdpipe”);
mkfifo(“cmdpipe”,0777);
fd=打开(“cmdpipe”,0777);
dup2(fd,标准文件号);
关闭(fd);
如果(arg[0]='\0')
execlp(cmd,cmd,NULL);
其他的
execlp(cmd、cmd、arg、NULL);
}
否则{
等待(空);
printf(“…输出就绪!正在显示。\n”);
fd=打开(“cmdpipe”,0777);
如果((n=read(fd,buf,BUFSIZE))<0){
perror(“管道读数错误”);
返回n;
}
关闭(fd);
printf(“%s\n”,buf);
}
返回0;
}
谢谢。在子级退出之前,父级不会打开命令管道FIFO,此时子级写入FIFO的任何数据都已被删除。
fd=open(“cmdpipe”,0777)
调用非常糟糕-这看起来像一组权限,但您已经通过了需要模式的地方,例如O_RDONLY
(在父级中;O_WRONLY
)。另外,read()
不会为null终止数据-您的打印不可靠。您需要检查错误,特别是在open()
中。检查呼叫的返回状态。我希望open
将阻塞,直到父级打开fifo进行读取。因此,如果open
返回,它可能返回了一个错误……您忽略了这个错误。感谢您的回答,它们非常有用。我首先让父级创建并打开管道,解决了这个问题;然后父级等待子级打开管道,将输出重定向到管道,执行命令;然后父级从管道中读取并打印。直到子级退出后,父级才打开命令管道FIFO,此时子级写入FIFO的任何数据都已被删除。fd=open(“cmdpipe”,0777)
调用非常糟糕-这看起来像一组权限,但您已经通过了需要模式的地方,例如O_RDONLY
(在父级中;O_WRONLY
)。另外,read()
不会为null终止数据-您的打印不可靠。您需要检查错误,特别是在open()
中。检查呼叫的返回状态。我希望open
将阻塞,直到父级打开fifo进行读取。因此,如果open
返回,它可能返回了一个错误……您忽略了这个错误。感谢您的回答,它们非常有用。我首先让父级创建并打开管道,解决了这个问题;然后父级等待子级打开管道,将输出重定向到管道,执行命令;然后父对象从管道中读取数据并打印。