Вам придется использовать pipe()
для создания новых стандартных выходных данных и, необязательно, стандартных дескрипторов файлов ошибок для каждой команды.Затем вы можете прочитать каналы по порядку, пока каждая команда не завершится.
В противном случае, поскольку каждая команда разветвляется в свой собственный процесс, она будет выполняться по своему усмотрению.Вывод текста из команд, выполняющихся одновременно и выдающих вывод на один и тот же терминал, может быть перепутан даже больше, чем показано здесь.
Может быть что-то вроде
#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);
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);
}
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;
}