2017-07-14 107 views
-1

我试图使用forkexecvp同时运行两个shell命令。我有两个问题,当我输入mkdir folder1&mkdir folder2时,它会创建一个名为folder1的文件夹和另一个名为folder2?(该问号包含在文件夹名称中)的文件夹。另一个问题是执行这两个命令后代码退出。即使循环条件仍然有效,为什么我的代码以退出代码退出:0?

下面是代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 

#define MAXLINE 80 /* The maximum length command */ 

int main(void) { 
    char *args [MAXLINE/2 + 1]; /* command line arguments */ 
    char *line = (char *) malloc((MAXLINE + 1) * sizeof (char)); 
    char *firstCommand = (char *) malloc((MAXLINE + 1) * sizeof (char)); 
    char *secondCommand = (char *) malloc((MAXLINE + 1) * sizeof (char)); 
    int shouldrun = 1; /* flag to determine when to exit program */ 
    pid_t pid; 
    while (shouldrun) { 
     printf("osh>"); 
     fflush(stdout); 
     fgets(line, MAXLINE, stdin); 
     if (strncmp(line, "exit", 4) == 0) { 
      shouldrun = 0; 
     } else { 
      firstCommand = strsep(&line, "&"); 
      secondCommand = strsep(&line, "&"); 
      pid = fork(); 
      if (pid == 0) { 
       // child 
       if (secondCommand != NULL) { 
        char *token; 
        int n = 0; 
        do { 
         token = strsep(&secondCommand, " "); 
         args[n] = token; 
         n++; 
        } while (token != NULL); 
        execvp(args[0], args); 
       } 
      } else { 
       // parent 
       char *token; 
       int n = 0; 
       do { 
        token = strsep(&firstCommand, " "); 
        args[n] = token; 
        n++; 
       } while (token != NULL); 
       execvp(args[0], args); 
      } 
     } 
    } 
    return 0; 
} 

更新1:

我试图按照凯文的答案。我试图同时执行多个进程,例如ps&ls&who&date。我尝试了一个递归方法,它给了我相同的行为。这里是我的代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 

#define MAXLINE 80 /* The maximum length command */ 

void execute(char *command) { 
    char *args [MAXLINE/2 + 1]; /* command line arguments */ 
    char *parentCommand = strsep(&command, "&"); 
    pid_t pid = fork();; 
    if (pid == 0) { 
     // child 
     if (command != NULL) { 
      execute(command); 
     } 
    } else { 
     // parent 
     char *token; 
     int n = 0; 
     do { 
      token = strsep(&parentCommand, " "); 
      args[n] = token; 
      n++; 
     } while (token != NULL); 
     execvp(args[0], args); 
    } 
} 

int main(void) { 
    char *line = (char *) malloc((MAXLINE + 1) * sizeof (char)); 
    int shouldrun = 1; /* flag to determine when to exit program */ 
    while (shouldrun) { 
     printf("osh>"); 
     fflush(stdout); 
     fgets(line, MAXLINE, stdin); 
     if (strncmp(line, "exit", 4) == 0) { 
      shouldrun = 0; 
     } else { 
      execute(line); 
     } 
    } 
    return 0; 
} 
+0

不确定你的问题的第一部分,但我看到1调用'fork'和2调用'execvp'。如果成功,'execvp'不会返回。没有什么会回到再次运行循环。 – Kevin

+0

@Kevin这是有道理的,那么如何执行'execvp'并返回到循环? – Ambitions

+0

请参阅我的答案。 – Kevin

回答

0

关于第一个问题,你需要从线截断\n。关于第二个问题,您可以使用功能system头文件,它不会终止您的程序。

1

你对为什么不循环,你打电话fork一次,而是调用execvp两次的问题。如果成功,execvp将不会返回。没有什么会回到再次运行循环。您需要做的是每个execvp拨打fork一次。我建议你移动forkexecvp调用一个单独的函数:

void run_command(const char* command) { 
    /* I suggest you also check for errors here */ 
    pid_t pid = fork(); 
    if (pid == 0) { 
     /* get args, call execvp */ 
    } 
} 

/* in your loop */ 
run_command(firstCommand); 
run_command(secondCommand); 
+0

在这种情况下,这两个命令不会同时运行,我想输入两个shell命令,并在它们之间使用&符号并使用分叉同时运行它们。 – Ambitions

+0

你为什么认为他们不会同时运行?我的代码不包含任何等待。 – Kevin