c程序,带有管道,以执行“EXECUTE”;ps aux“grep firefox”tee processs.txt“;

c程序,带有管道,以执行“EXECUTE”;ps aux“grep firefox”tee processs.txt“;,c,linux,pipe,C,Linux,Pipe,这是我的第一个问题。希望不会是达姆。我在编写一个生成“ps aux | grep firefox | tee processs.txt”的程序时遇到了问题。我成功地使用了1个类似于“ps aux | grep firefox”的管道,但当我尝试推广时,我遇到了问题。我的意图是使用管道来理解它们。我知道这是可能的开放。任何暗示都很好 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #inclu

这是我的第一个问题。希望不会是达姆。我在编写一个生成“ps aux | grep firefox | tee processs.txt”的程序时遇到了问题。我成功地使用了1个类似于“ps aux | grep firefox”的管道,但当我尝试推广时,我遇到了问题。我的意图是使用管道来理解它们。我知道这是可能的开放。任何暗示都很好

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> 
#include <sys/wait.h>
#include <sys/types.h>
int main(void)
{
    char *** args = NULL;
    pid_t fork_id = -1;
    int ** pipes = NULL;
    int status = 0;
    int i = 0, k = 0;
    int check = 0;
    args = calloc(3, sizeof(char **));
    args [0] = calloc(3, sizeof(char *));
    args [1] = calloc(3, sizeof(char *));
    args [2] = calloc(3, sizeof(char *));
    args[0][0]= "ps";
    args[0][1]="aux";
    args[0][2]= NULL;
    args[1][0]= "grep";
    args[1][1]= "firefox";
    args[1][2]= NULL;
    args[2][0]= "tee";
    args[2][1]= "processes.txt";
    args[2][2]= NULL;

    pipes=calloc(2,sizeof(int *));
    for(i=0;i<2;++i){
        pipes[i]=calloc(2,sizeof(int));
    }
    for(i=0;i<2;++i){
        pipes[i]=calloc(2,sizeof(int));
        check=pipe(pipes[i]);
        if(check<0){
            perror("pipe");
            exit(EXIT_FAILURE);
        }
    }
    for(i=0;i<3;++i){
        if ((fork_id = fork()) < 0) {
            perror("fork()");
            exit(1);
        }
        if ((i ==0)&& (fork_id == 0)){ 
        close(pipes[i][0]);
        close(1);
        dup(pipes[i][1]);
        close(pipes[i][1]);
        execvp(args[i][0], args[0]);
        } else if ((i!= 0)&&(i  != 2) && (fork_id == 0)){
            close(0);
            dup(pipes[i][0]);
            close(pipes[i][0]);
            close(1);
            dup(pipes[i][1]);
            close(pipes[i][1]);
            execvp(args[i][0], args[i]);
        } else if ((i==2)&&(fork_id != 0)){
            close(pipes[i-1][1]);
            close(0);
            dup(pipes[i-1][0]);
            close(pipes[i-1][0]);
            execvp(args[i][0], args[i]);
        }
        wait(&status);
    }
    for(i=0;i<2;++i){
        for(k=0;k<2;++k){
            check=close(pipes[i][k]);
            if(check<0){
                perror("close pipe");
                    exit(EXIT_FAILURE);
            }
        }
    }
    return(0);
}
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
字符***args=NULL;
pid\u t fork\u id=-1;
int**pipes=NULL;
int status=0;
int i=0,k=0;
整数检查=0;
args=calloc(3,sizeof(char**));
args[0]=calloc(3,sizeof(char*);
args[1]=calloc(3,sizeof(char*);
args[2]=calloc(3,sizeof(char*);
args[0][0]=“ps”;
args[0][1]=“辅助”;
args[0][2]=NULL;
args[1][0]=“grep”;
args[1][1]=“firefox”;
args[1][2]=NULL;
args[2][0]=“T”;
args[2][1]=“processs.txt”;
args[2][2]=NULL;
管道=calloc(2,尺寸f(int*);

对于(i=0;iPopen),您可能会感兴趣

FILE *p = popen("ps aux | grep firefox | tee processes.txt", "r");

这可能就是您想要的-不需要所有这些执行官、分叉和管道:

#include <stdio.h>                                                              
#include <stdlib.h>

int main() {
  FILE *p; 
  int status;
  char line[1024];

  p = popen("ps aux | grep firefox | tee processes.txt", "r");
  if (!p) {
    fprintf(stderr, "Error.");
    exit(1);
  }

  while (fgets(line, sizeof(line) - 1, p)) {
    puts(line);
  }
  pclose(p);
}
#包括
#包括
int main(){
文件*p;
智力状态;
字符行[1024];
p=popen(“ps aux | grep firefox | tee processs.txt”,“r”);
如果(!p){
fprintf(标准“错误”);
出口(1);
}
while(fgets(line,sizeof(line)-1,p)){
放(线);
}
pclose(p);
}
可接受的解决方案仅适用于此管道:

/*
** How to create a pipeline of N processes?
** SO 18582446: ps aux | grep firefox | tee processes.txt
** Adaptation of accepted answer to:
** SO 13636252 C Minishell adding pipelines
*/

/* stderr.h */
#ifndef STDERR_H_INCLUDED
#define STDERR_H_INCLUDED

static void err_setarg0(const char *argv0);
static void err_sysexit(char const *fmt, ...);
static void err_syswarn(char const *fmt, ...);

#endif /* STDERR_H_INCLUDED */

/* pipeline.c */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
/*#include "stderr.h"*/

typedef int Pipe[2];

/* Now: ps aux | grep firefox | tee processes.txt */
/* Was: who | awk '{print $1}' | sort | uniq -c | sort -n */
static char *cmd0[] = { "ps",   "aux",           0 };
static char *cmd1[] = { "grep", "firefox",       0 };
static char *cmd2[] = { "tee",  "processes.txt", 0 };

static char **cmds[] = { cmd0, cmd1, cmd2, };
static int   ncmds = sizeof(cmds) / sizeof(cmds[0]);

/* exec_nth_command() and exec_pipe_command() are mutually recursive */
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output);

/* With the standard output plumbing sorted, execute Nth command */
static void exec_nth_command(int ncmds, char ***cmds)
{
    assert(ncmds >= 1);
    if (ncmds > 1)
    {
        pid_t pid;
        Pipe input;
        if (pipe(input) != 0)
            err_sysexit("Failed to create pipe");
        if ((pid = fork()) < 0)
            err_sysexit("Failed to fork");
        if (pid == 0)
        {
            /* Child */
            exec_pipe_command(ncmds-1, cmds, input);
        }
        /* Fix standard input to read end of pipe */
        dup2(input[0], 0);
        close(input[0]);
        close(input[1]);
    }
    execvp(cmds[ncmds-1][0], cmds[ncmds-1]);
    err_sysexit("Failed to exec %s", cmds[ncmds-1][0]);
    /*NOTREACHED*/
}

/* Given pipe, plumb it to standard output, then execute Nth command */
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output)
{
    assert(ncmds >= 1);
    /* Fix stdout to write end of pipe */
    dup2(output[1], 1);
    close(output[0]);
    close(output[1]);
    exec_nth_command(ncmds, cmds);
}

/* Execute the N commands in the pipeline */
static void exec_pipeline(int ncmds, char ***cmds)
{
    assert(ncmds >= 1);
    pid_t pid;
    if ((pid = fork()) < 0)
        err_syswarn("Failed to fork");
    if (pid != 0)
        return;
    exec_nth_command(ncmds, cmds);
}

/* Collect dead children until there are none left */
static void corpse_collector(void)
{
    pid_t parent = getpid();
    pid_t corpse;
    int   status;
    while ((corpse = waitpid(0, &status, 0)) != -1)
    {
        fprintf(stderr, "%d: child %d status 0x%.4X\n",
                (int)parent, (int)corpse, status);
    }
}

static void exec_arguments(int argc, char **argv)
{
    /* Split the command line into sequences of arguments */
    /* Break at pipe symbols as arguments on their own */
    char **cmdv[argc/2];            // Way too many
    char  *args[argc+1];
    int cmdn = 0;
    int argn = 0;

    cmdv[cmdn++] = &args[argn];
    for (int i = 1; i < argc; i++)
    {
        char *arg = argv[i];
        if (strcmp(arg, "|") == 0)
        {
            if (i == 1)
                err_sysexit("Syntax error: pipe before any command");
            if (args[argn-1] == 0)
                err_sysexit("Syntax error: two pipes with no command between");
            arg = 0;
        }
        args[argn++] = arg;
        if (arg == 0)
            cmdv[cmdn++] = &args[argn];
    }
    if (args[argn-1] == 0)
        err_sysexit("Syntax error: pipe with no command following");
    args[argn] = 0;
    exec_pipeline(cmdn, cmdv);
}

#include <signal.h>

typedef void (*SigHandler)(int signum);

static void sigchld_status(void)
{
    const char *handling = "Handler";
    SigHandler sigchld = signal(SIGCHLD, SIG_IGN);
    signal(SIGCHLD, sigchld);
    if (sigchld == SIG_IGN)
        handling = "Ignored";
    else if (sigchld == SIG_DFL)
        handling = "Default";
    printf("SIGCHLD set to %s\n", handling);
}

int main(int argc, char **argv)
{
    err_setarg0(argv[0]);
    sigchld_status();
    if (argc == 1)
    {
        /* Run the built in pipe-line */
        exec_pipeline(ncmds, cmds); 
    }
    else
    {
        /* Run command line specified by user */
        exec_arguments(argc, argv);
    }
    corpse_collector();
    return(0);
}

/* stderr.c */
/*#include "stderr.h"*/
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

static const char *arg0 = "<undefined>";

static void err_setarg0(const char *argv0)
{
    arg0 = argv0;
}

static void err_vsyswarn(char const *fmt, va_list args)
{
    int errnum = errno;
    fprintf(stderr, "%s:%d: ", arg0, (int)getpid());
    vfprintf(stderr, fmt, args);
    if (errnum != 0)
        fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
    putc('\n', stderr);
}

static void err_syswarn(char const *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    err_vsyswarn(fmt, args);
    va_end(args);
}

static void err_sysexit(char const *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    err_vsyswarn(fmt, args);
    va_end(args);
    exit(1);
}
/*
**如何创建N个进程的管道?
**所以18582446:ps aux | grep firefox | tee processs.txt
**将公认答案改编为:
**因此,13636252 C微型管添加管道
*/
/*标准*/
#如果不包括标准的话
#定义包含的标准
静态无效错误设置arg0(常量字符*argv0);
静态void err_sysexit(字符常量*fmt,…);
静态void err_syswarn(字符常量*fmt,…);
#endif/*包括标准件*/
/*管道c*/
#包括
#包括
#包括
#包括
#包括
/*#包括“stderr.h”*/
类型定义内部管道[2];
/*现在:ps aux | grep firefox | tee processs.txt*/
/*Was:who | awk{print$1}| sort | uniq-c | sort-n*/
静态字符*cmd0[]={“ps”,“aux”,0};
静态字符*cmd1[]={“grep”,“firefox”,0};
静态字符*cmd2[]={“tee”,“processs.txt”,0};
静态字符**cmds[]={cmd0,cmd1,cmd2,};
静态int-ncmds=sizeof(cmds)/sizeof(cmds[0]);
/*exec\u nth\u command()和exec\u pipe\u command()是相互递归的*/
静态void exec_pipe_命令(int-ncmds、char***cmds、pipe-output);
/*对标准输出管道进行排序后,执行第n个命令*/
静态void exec\u nth\u命令(int-ncmds、char***cmds)
{
断言(ncmds>=1);
如果(ncmds>1)
{
pid_t pid;
管道输入;
如果(管道(输入)!=0)
err_sysexit(“未能创建管道”);
如果((pid=fork())<0)
err_sysexit(“未能分叉”);
如果(pid==0)
{
/*孩子*/
exec_pipe_命令(ncmds-1,cmds,输入);
}
/*固定标准输入以读取管道末端*/
dup2(输入[0],0);
关闭(输入[0]);
关闭(输入[1]);
}
execvp(cmds[ncmds-1][0],cmds[ncmds-1]);
err_sysexit(“未能执行%s”,cmds[ncmds-1][0]);
/*未到达*/
}
/*给定管道,使其垂直于标准输出,然后执行第n个命令*/
静态void exec_pipe_命令(int-ncmds、char***cmds、管道输出)
{
断言(ncmds>=1);
/*将标准输出固定到管道末端*/
dup2(输出[1],1);
关闭(输出[0]);
关闭(输出[1]);
执行命令(ncmds、cmds);
}
/*在管道中执行N个命令*/
静态void exec_管道(int-ncmds、char***cmds)
{
断言(ncmds>=1);
pid_t pid;
如果((pid=fork())<0)
err_syswarn(“未能分叉”);
如果(pid!=0)
返回;
执行命令(ncmds、cmds);
}
/*收集死去的孩子,直到一个也没有留下*/
静态无效尸体收集器(无效)
{
pid_t parent=getpid();
尸体;
智力状态;
while((尸体=waitpid(0,&status,0))!=-1)
{
fprintf(stderr,“%d:子%d状态0x%.4X\n”,
(int)父母,(int)尸体,身份);
}
}
静态void exec_参数(int argc,char**argv)
{
/*将命令行拆分为参数序列*/
/*管道符号本身作为参数的打断*/
char**cmdv[argc/2];//太多了
字符*args[argc+1];
int-cmdn=0;
int argn=0;
cmdv[cmdn++]=&args[argn];
对于(int i=1;i