我一直在努力创建一个程序来读取shell命令并像
那样执行它们ls -l | sort > there.txt
然而,我所做的并没有执行第二个命令。 我仍然是c编程的新手,我根本不熟悉fork()和pipe(),所以如果我所做的事情有很多错误我也不会感到惊讶。 如果有人可以帮助我会很感激。 提前谢谢
这是我的代码:
COMMON.H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
void runThat(char* cmd1[], char* cmd2[]);
common.c:
#include "common.h"
void runThat(char* cmd1[], char *cmd2[]){
pid_t pid, waitPid;
int pipefd[2];
int status;
pipe(pipefd);
pid = fork();
if (pid<0){
perror("Fork has failed");
exit(1);
}
else if (pid==0){
dup2(pipefd[0],0);
close(pipefd[1]);
if (execvp(cmd1[0],cmd1)==-1){
perror("Error");
exit(1);
}
}
else{
waitPid = wait(&status);
if (waitPid == -1){
perror("Waitpid failed");
exit(1);
}
dup2(pipefd[1],1);
close(pipefd[0]);
if (execvp(cmd2[0],cmd2)==-1){
perror("Error");
exit(1);
}
}
}
主要是:
#include "common.h"
#define BUFFER 300
int main(void){
char * buffer = (char*)malloc(sizeof(char)* BUFFER);
unsigned int buffer_length;
char* tkn;
char * param[BUFFER];
char * cmd1[BUFFER];
char * cmd2[BUFFER];
char *filename = NULL;
char *output = NULL;
int append = 0;
int f1;
int f2;
int saved_stdin = dup(0);
int saved_stdout = dup(1);
printf("mysh4> ");
while (1){
filename = NULL;
output = NULL;
memset(buffer,0,BUFFER);
int input = getline(&buffer,&buffer_length,stdin);
if (input==-1){
printf("\n");
exit(1);
}
if (input>BUFFER){
printf("Error. Comand must not exceed %d characters.\n",BUFFER);
exit(1);
}
switch(input){
case 1:
printf("mysh4> ");
break;
default:
if ((strcmp(buffer,"exit\n")==0)||(strcmp(buffer,"terma\n")==0)||(strcmp(buffer,"end\n")==0)) {
printf("EXIT\n");
exit(1);
}
else {
int i =0; int j=0;
tkn = strtok(buffer," \t\n");
int NOP = 0;
while (tkn != NULL){
if(strcmp(tkn,"<")==0){
filename = tkn = strtok(NULL," \t\n");
}
else if(strcmp(tkn,">")==0){
output = tkn = strtok(NULL," \t\n");
append =0;
}
else if(strcmp(tkn,">>")==0){
output = tkn = strtok(NULL," \t\n");
append =1;
}
if(strcmp(tkn,"|")==0){
NOP++;
//param[i++] = NULL;
}
//else
param[i++] = tkn;
tkn = strtok(NULL, " \t\n");
}
param[i] = NULL;
i=0; j=0;
while (param[i]!= NULL){
if (strcmp(param[i],"|")==0) break;
cmd1[i] = param[i];
i++;
}
cmd1[i] = NULL;
while (param[i]!=NULL){
if (strcmp(param[i],"|")==0) i++;
cmd2[j] = param[i];
j++; i++;
}
cmd2[j] = NULL;
i=0;
while (cmd1[i]!=NULL){
printf("cmd1 HAS:[%s]\n", cmd1[i++]); // TO BE DELETED
if (cmd1[i]==NULL){
printf("cmd1 HAS:[NULL]\n");
}
}
i=0;
while (cmd2[i]!=NULL){
printf("cmd2 HAS:[%s]\n", cmd2[i++]); // TO BE DELETED
if (cmd2[i]==NULL){
printf("cmd2 HAS:[NULL]\n");
}
}
printf("FILENAME :[%s]\n", filename);
printf("OUTPUT: [%s]\n", output);
if (filename){
f1 = open(filename,O_APPEND | O_RDONLY);
if(dup2(f1,0) < 0) {
perror("Dup2:Input failed."); exit(1);
}
close(f1);
}
if (output){
if(append == 0)
f2 = open(output,O_WRONLY | O_CREAT | O_TRUNC, 0777);//TRUNC:ta sbhnei
else
f2 = open(output,O_WRONLY | O_CREAT | O_APPEND, 0777);
if(dup2(f2,1) < 0) {
perror("Dup2:Output failed."); exit(1);
}
close(f2);
}
runThat(cmd1,cmd2);
dup2(saved_stdin,0);
dup2(saved_stdout,1);
printf("mysh4> ");
break;
}//else
}//switch
}//while
free(buffer);
return 0;
}
编辑:经过大量搜索后,我发现了一些与我有类似问题的人发帖。在我的程序中应用建议的答案我最终得到了以下功能。但是,现在当我输入像“ls -l”这样的命令时,它似乎运行了两次
total 40
-rw-rw-r-- 1 csuser csuser 1553 Μάι 12 18:27 common.c
-rw-rw-r-- 1 csuser csuser 313 Μάι 12 17:00 common.h
-rwxrwxr-x 1 csuser csuser 12204 Μάι 12 18:25 m
-rw-rw-r-- 1 csuser csuser 2534 Μάι 12 18:00 mysh4.c
-rw-rw-r-- 1 csuser csuser 7395 Μάι 12 12:44 p3090278-mysh4.c
-rwxrwxr-x 1 csuser csuser 59 Μάι 12 17:46 that
-rwxrwxr-x 1 csuser csuser 22 Μάι 12 18:13 there
csuser@CSLAB2:~/Desktop$ total 40
-rw-rw-r-- 1 csuser csuser 1553 Μάι 12 18:27 common.c
-rw-rw-r-- 1 csuser csuser 313 Μάι 12 17:00 common.h
-rwxrwxr-x 1 csuser csuser 12204 Μάι 12 18:25 m
-rw-rw-r-- 1 csuser csuser 2534 Μάι 12 18:00 mysh4.c
-rw-rw-r-- 1 csuser csuser 7395 Μάι 12 12:44 p3090278-mysh4.c
-rwxrwxr-x 1 csuser csuser 59 Μάι 12 17:46 that
-rwxrwxr-x 1 csuser csuser 22 Μάι 12 18:13 there
我也编辑了我的主要课程,但我测试了它并且没有任何问题,所以下面的代码再次出现问题。它应该能够运行无管道或多管道
void runThat(char *cmds[][MAX_PAR], int NOP){
pid_t pid, waitPid;
int status;
int pipefd[2];
int Num_Cmds = NOP +1;
int r[Num_Cmds]; int w[Num_Cmds];
char ** cmd;
for (int i = 0; i < Num_Cmds; i++){
r[i] = -1;
w[i] = -1;
}
for (int j = 0; j < NOP; j++){
pipe(pipefd);
r[j+1] = pipefd[0];
w[j] = pipefd[1];
}
for (int i = 0; i < Num_Cmds; i++){
int h = 0;
while (cmds[i][h]!= NULL){
cmd[h] = cmds[i][h];
printf("This [%s]\n", cmd[h]);
h++;
}
cmd[h] = NULL;
printf("This [%s]\n", cmd[h]);
if (pid = fork() < 0){
perror("Fork has failed");
exit(1);
}
else if(pid == 0){
if (r[i] != -1){
close(STDIN_FILENO);
dup2(r[i],STDIN_FILENO);
}
if (w[i] != -1){
close(STDOUT_FILENO);
dup2(w[i],STDOUT_FILENO);
}
for (int j = 0; j < Num_Cmds; j++){
close(w[j]);
close(r[j]);
}
if (execvp(cmd[0], cmd)==-1){
perror("Command Failed");
exit(0);
}
}
else{
waitPid = wait(&status);
if (waitPid == -1){
perror("Waitpid failed");
exit(1);
}
close(w[i]);
if (i>0){
close(r[i]);
}
}
}
}