多叉并在执行前打印一些东西 [英] Multiple fork and printing something before exec

查看:66
本文介绍了多叉并在执行前打印一些东西的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

// I have commands in commands[] array
pid_t pid[command_count];

for (int i = 0; i < command_count; i++) {
  if ((pid[i]=fork()) == 0) {
      printf("--%s\n", commands[i][0]);
      execvp(commands[i][0],commands[i]);
      _exit(1);
  }
  if (pid[i] < 0) {

  }
}

for (i = 0; i < command_count; i++) { 
  if (pid[i] > 0) {
    int status;
    waitpid(pid[i], &status, 0);
  }    
}

我有上面的代码,想要立即(并行)运行命令数组中的命令,并且在每次运行之前都想打印命令.例如;

I have the above code and want to run commands at once (paralel) that is in commands array and before each run, want to print the command. For example;

ls | pwd | ls -a

在运行该命令之前,它应该打印每个命令名称

It should print each command name before that command run like

--ls
.. a b.txt
--pwd
/a/a/
--ls -a
*some output*

但它的打印内容如下

--ls
--pwd
--ls -a
.. a b.txt
*some directory as a result of pwd*
*some output*  

可能是什么原因,我该如何解决?

What could be the reason and how can I fix it?

推荐答案

您将必须使用 pipe()为每个命令创建新的标准输出以及可选的标准错误文件描述符.然后,您可以按顺序读取管道,直到每个命令完成为止.

You will have to use pipe() to create new standard output and optionally standard error file descriptors for each command. Then you can read the pipes in order until each command completes.

否则,因为每个命令都被分叉到自己的进程中,所以它将在自己方便的时候运行.一次运行的命令输出的文本输出到同一终端的输出结果可能比您在此处显示的更多.

Otherwise, because each command is forked into its own process it will run at its own convenience. Text output from commands running all at once and producing output to the same terminal can be mixed up even more than you show here.

也许像

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

struct cmd_data {
    const char *cmd;
    int fd[2];  // stdout pipe for command
    pid_t pid;
    int status; // exit status
};

void cmd_launch(struct cmd_data *p, const char *cmd) {
    int r;

    p->cmd = cmd;
    r = pipe(p->fd);
    if(r<0) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    r = fork();
    if(r < 0) {
        perror("fork");
        close(p->fd[0]);
        close(p->fd[1]);
    } else if( r > 0 ) {
        p->pid = r;
        close(p->fd[1]);
    } else {
        close(p->fd[0]);
        dup2(p->fd[1], STDOUT_FILENO);
        close(p->fd[1]);
        r = execlp(cmd, cmd, NULL);
        perror("execlp");
        exit(EXIT_FAILURE);
    }
}

void cmd_join(struct cmd_data *p) {
    char buf[4096];
    const size_t buflen = sizeof buf;
    ssize_t bytes;

    printf("-- %s\n", p->cmd);
    fflush(stdout);
    while( 0 != (bytes = read(p->fd[0], buf, buflen)) ) {
        write(STDOUT_FILENO, buf, bytes);
    }
    close(p->fd[0]);
    pid_t r = waitpid(p->pid, &p->status, 0);
    if(r<0){
        perror("waitpid");
    }
    printf("-- completed with status %d\n", p->status);
    fflush(stdout);
}

int main(int argc, char *argv[]) {
    size_t cmd_c = argc - 1;
    struct cmd_data *p = calloc(argc, sizeof *p);
    size_t i;

    for(i = 0; i < cmd_c; ++i) {
        cmd_launch(p + i, argv[i + 1]);
    }

    for(i = 0; i < cmd_c; ++i) {
        cmd_join(p + i);
    }

    free(p);
    return EXIT_SUCCESS;
}

这篇关于多叉并在执行前打印一些东西的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆