I created my own shell and try to execute a command in my shell using multiple pipes. I implemented the shell so that I can run this command cat a.txt b.txt | egrep ‘g’ | sort | more > ab.txt
The contain of the a.txt file is
alligator
agile
metro
plane
The contain of the b.txt file is
spring
age
hot
high
cold
The output of the ab.txt file should be
alligator
agile
spring
age
high
But after running the code I received an empty ab.txt file. I did not understand what is wrong in my code.
The code block is as follows
#define MAX_LINE 50
#define MAX_PIPES 5
void execute_command(char *args[], int in_fd, int out_fd);
int main(void) {
char *args[MAX_LINE/2 + 1];
char line[MAX_LINE];
int should_run = 1;
while (should_run) {
printf("$ ");
fflush(stdout);
if (fgets(line, MAX_LINE, stdin) == NULL) {
break; /* End of file (Ctrl+D) */
}
line[strcspn(line, "\n")] = 0;
/* Parse the line into separate commands for pipes */
char *commands[MAX_PIPES + 1];
int num_cmds = 0;
char *cmd = strtok(line, "|");
while (cmd != NULL && num_cmds < MAX_PIPES) {
commands[num_cmds++] = cmd;
cmd = strtok(NULL, "|");
}
commands[num_cmds] = NULL;
if (num_cmds == 0) {
continue;
}
if (strcmp(commands[0], "exit") == 0) {
should_run = 0;
continue;
} else if (strncmp(commands[0], "cd ", 3) == 0) {
char *dir = commands[0] + 3;
if (chdir(dir) != 0) {
perror("chdir");
}
continue;
}
/* Create pipes for the commands */
int pipe_fds[MAX_PIPES][2];
for (int i = 0; i < num_cmds - 1; i++) {
if (pipe(pipe_fds[i]) == -1) {
perror("pipe");
exit(1);
}
}
/* Execute each command in the pipeline */
for (int i = 0; i < num_cmds; i++) {
/* Parse the command into arguments */
int argc = 0;
char *args[MAX_LINE/2 + 1];
char *token = strtok(commands[i], " \t");
while (token != NULL) {
args[argc++] = token;
token = strtok(NULL, " \t");
}
args[argc] = NULL;
pid_t pid = fork();
if (pid == 0) {
if (i > 0) {
dup2(pipe_fds[i - 1][0], STDIN_FILENO);
}
if (i < num_cmds - 1) {
dup2(pipe_fds[i][1], STDOUT_FILENO);
}
/* Close all pipes */
for (int j = 0; j < num_cmds - 1; j++) {
close(pipe_fds[j][0]);
close(pipe_fds[j][1]);
}
if (i == num_cmds - 1) {
for (int j = 0; args[j] != NULL; j++) {
if (strcmp(args[j], ">") == 0) {
args[j] = NULL;
int fd = open(args[j + 1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open");
exit(1);
}
dup2(fd, STDOUT_FILENO);
close(fd);
break;
}
}
}
/* Execute the command */
execvp(args[0], args);
perror("execvp");
exit(1);
} else if (pid < 0) { /* Fork failed */
perror("fork");
exit(1);
}
}
for (int i = 0; i < num_cmds - 1; i++) {
close(pipe_fds[i][0]);
close(pipe_fds[i][1]);
}
for (int i = 0; i < num_cmds; i++) {
wait(NULL);
}
}
return 0;
}
I am using the operating system Ubuntu 20.04. Any help would be appreciated.
You need to sign in to view this answers
Leave feedback about this