// 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);
}
}
我有上面的代码,想要立即(并行)运行命令数组中的命令,并且在每次运行之前,想要打印命令。例如;
ls | pwd | ls -a
它应该在命令运行之前打印每个命令名称
--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*
可能是什么原因以及如何解决它?
最佳答案
您必须使用pipe()
为每个命令创建新的标准输出和可选的标准错误文件描述符。然后您可以按顺序读取管道,直到每个命令完成。
否则,因为每个命令都被 fork 到自己的进程中,所以它将在自己方便的时候运行。同时运行所有命令并向同一终端生成输出的文本输出可能会比此处显示的更加困惑。
也许是这样的
#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;
}
关于c - 多次 fork 并在 exec 之前打印一些内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58140268/