Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在命名管道中存储Linux命令的输出_C_Fork_Exec_Named Pipes - Fatal编程技术网

C 在命名管道中存储Linux命令的输出

C 在命名管道中存储Linux命令的输出,c,fork,exec,named-pipes,C,Fork,Exec,Named Pipes,我的目标是获取用户输入的命令,并使用分叉子进程执行它,而不是让子进程将其打印到屏幕上,将输出存储在命名管道中,并让父进程在子进程完成后显示输出 我尝试使用dup2()将标准输出重定向到我制作的命名管道,但子进程只是打印命令的输出,当尝试在父进程中读取管道时,我得到以下错误: 读取管道时出错:错误的文件描述符 我在这个网站上搜索过类似的问题,但只找到了使用常规管道存储exec()输出的解决方案,我无法将这些解决方案应用于命名管道。这是我的密码: #include <stdio.h>

我的目标是获取用户输入的命令,并使用分叉子进程执行它,而不是让子进程将其打印到屏幕上,将输出存储在命名管道中,并让父进程在子进程完成后显示输出

我尝试使用dup2()将标准输出重定向到我制作的命名管道,但子进程只是打印命令的输出,当尝试在父进程中读取管道时,我得到以下错误:

读取管道时出错:错误的文件描述符

我在这个网站上搜索过类似的问题,但只找到了使用常规管道存储exec()输出的解决方案,我无法将这些解决方案应用于命名管道。这是我的密码:

 #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
返回,它可能返回了一个错误……您忽略了这个错误。感谢您的回答,它们非常有用。我首先让父级创建并打开管道,解决了这个问题;然后父级等待子级打开管道,将输出重定向到管道,执行命令;然后父对象从管道中读取数据并打印。