2016-01-20 108 views
0

我是新的与unix,我有一个在大学的assignemnt建立一个简单的shell在c内置cd和杀死命令.. 这是我的代码不工作..tbh我不明白这是最好的,所以我不惊讶它不工作..你能帮我吗?也不知道我将如何执行kill命令。谢谢!建立简单的unix外壳问题

#include <sys/wait.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#define BUF_SIZE 1024 



const int ARGSIZE = 20; 

void execute(char*args[]) 
{ 

    int pid, status; 
    pid = fork(); 

    if(pid<0) 
    { 
     perror("Error forking!"); 
    } 

    else if(pid > 0) 
    { 
     while(wait(&status) != pid) 
      continue; 
    } 

    else if(pid == 0) 
    { 
    if (execvp(args[0], args) == -1) 
    { 
     perror("Error"); 
    } 
    } 
} 

void cd(char*directory) 
{ 
    int ret = 0; 

    if(directory == '\0') 
     directory = getenv("HOME"); 

    ret = chdir(directory); 

    if(ret != 0) 
     fprintf(stderr,"Failed to enter directory: %s\n",directory); 
    else 
     printf("%s\n",directory); 

} 


int main() 
{ 
    char line[BUF_SIZE]; 
    char *args[ARGSIZE]; 
    int argIndex = 0; 


    while(1){ 
    printf("> "); 

    fgets(line, BUF_SIZE, stdin); 
    char *token; 
    token = strtok(line," "); 

    while(token!=NULL) 
    { 
     args[argIndex]=token; 
     token = strtok(NULL," "); 
     argIndex++; 
    } 
    args[argIndex]=NULL; 


    if(strcmp(args[0], "quit") == 0 || strcmp(args[0], "exit") == 0) 
     break; 

    if(line== "\n") 
     printf("> "); 
    else if ((strcmp(args[0], "cd") == 0)) 
     cd(args[1]); 
    else 
     execute(args); 

    } 
    return 0; 
} 
+0

请参阅“man 2 kill”您还需要描述“不工作”的意思。您期望发生什么?发生了什么。 –

回答

0

你是在正确的轨道上。有几个细微的问题,如果你没有记录尾部'\n',它将保留在line中作为在提示符处输入的最后一个字符。在用于标记输入的分隔符中包括" \n"将使用strtok将其删除,从而允许与最终标记进行有效的strcmp比较(例如,这就是为什么quitexit不会退出应用程序)。

除了以外,您还可以做一些不同的更好的事情,例如,您可以处理输入的目录。 '~/somedir',以及可以使用的类似附加检查。作为对代码的评论,我在下面写了最多。

查看下面的变化,让我知道你是否有任何问题。总是有额外的检查可以添加等,但总的来说,你对问题的处理方式非常好。 (注:如你所愿一些所做的更改是非实质性的,如"shell> "作为提示,而不是"> "就处理任何那些

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 

enum {ARGSIZE = 20, BUF_SIZE = 1024}; 

void execute (char **args); 
void cd (char *directory); 
int killpid (char *pitstr, int sig); 

int main (void) 
{ 
    char line[BUF_SIZE] = {0}; 
    char *args[ARGSIZE] = {NULL}; 
    char *token; 
    int i, argIndex = 0; 

    while (1) { 

     argIndex = 0; /* reinitialize variables */ 
     for (i = 0; i < ARGSIZE; i++) 
      args[i] = NULL; 

     printf ("shell> "); /* prompt */ 

     if (fgets (line, BUF_SIZE, stdin) == NULL) { 
      printf ("EOF received\n"); 
      return 0; 
     } 
     if (*line == '\n') /* Enter alone */ 
      continue; 

     token = strtok (line, " \n"); /* add \n to delimiters */ 

     while (token != NULL) { 
      args[argIndex] = token; 
      token = strtok (NULL, " \n"); 
      argIndex++; 
     } 
     if (!argIndex) continue; /* validate at least 1 arg */ 

     if (strcmp (args[0], "quit") == 0 || strcmp (args[0], "exit") == 0) 
      break; 

     /* handle 'cd' or 'kill' separately */ 
     if ((strcmp (args[0], "cd") == 0)) 
      cd (args[1]); 
     else if ((strcmp (args[0], "kill") == 0)) { 
      if (args[1]) killpid (args[1], SIGTERM); 
     } 
     else 
      execute (args); 

    } 
    return 0; 
} 

void execute (char **args) 
{ 
    int pid, status; 
    pid = fork(); 

    if (pid < 0) { 
     perror ("Error forking!"); 
     return; 
    } 
    else if (pid > 0) { 
     while (wait (&status) != pid) 
      continue; 
    } 
    else if (pid == 0) { 
     if (execvp (args[0], args) == -1) { 
      perror ("Error"); 
     } 
     _exit (EXIT_FAILURE); 
    } 
} 

void cd (char *directory) 
{ 
    char dir[BUF_SIZE] = {0}; 

    if (!directory) { /* handle 'cd' */ 
     directory = getenv ("HOME"); 
     if (chdir (directory)) 
      fprintf (stderr, "Failed to enter directory: %s\n", directory); 
     else 
      printf ("%s\n", directory); 
     return; 
    } 

    if (*directory == '~') { /* handle cd ~/stuff */ 
     strcpy (dir, getenv ("HOME")); 
     strcat (dir, "/"); 
     strcat (dir, directory + 2); 
     if (chdir (dir)) 
      fprintf (stderr, "Failed to enter directory: %s\n", dir); 
     else 
      printf ("%s\n", dir); 
     return; 
    } 

    if (chdir (directory)) /* handle given directory */ 
     fprintf (stderr, "Failed to enter directory: %s\n", directory); 
    else 
     printf ("%s\n", directory); 
} 

int killpid (char *pidstr, int sig) 
{ 
    pid_t pid = (pid_t)atoi (pidstr); 
    if (pid < 1) { 
     fprintf (stderr, "warning: requested pid < 1, ignoring\n"); 
     return (int)pid; 
    } 

    printf (" killing pid '%d' with signal '%d'\n", (int)pid, sig); 
    // return kill (pid, sig); 
    return 0; 
} 

用法示例/输出

$ ./bin/ushell 
shell> cd 
/home/david 
shell> cd ~/tmp 
/home/david/tmp 
shell> kill 18004 
killing pid '18004' with signal '15' 
shell> 
shell> quit 
+0

非常感谢您的帮助。:)我现在明白了。 – Shallan