2017-07-14 108 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