繁体   English   中英

C Shell执行命令

[英]C Shell to execute commands

我有以下代码:

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

void  passe(char *ligne, char **argv)
{
     while (*ligne != '\0')
     {
          while (*ligne == ' ' || *ligne == '\t' || *ligne == '\n')
               *ligne++ = '\0';
          *argv++ = ligne;
          while (*ligne != '\0' && *ligne != ' ' &&  *ligne != '\t' && *ligne != '\n') 
               ligne++;   
     }
     *argv = '\0';
}

void  executer(char **argv)
{
     pid_t  pid;
     int    status;

     if ((pid=fork()) == 0)
     {
          if (execvp(*argv, argv) < 0) 
          {
               printf("*** ERREUR: exec echoué\n");
               exit(1);
          }
     }
     wait(&status);
}

int  main(void)
{
     char  ligne[1024];
     char  *argv[64];

     while (1)
     {
          printf("Shell -> ");
          scanf("%s",ligne);
          printf("\n");
          passe(ligne, argv);
          if (strcmp(argv[0], "exit") == 0)
               exit(0);
          executer(argv);
     }
     return 0;
}

该程序运行良好,但是当我解析“ ps -f”之类的内容时,它将重新调整“ execvpechoué”,因为代码会删除空格。 我应该怎么做才能使其接受诸如ps -f之类的命令?

您应该使用fgets()而不是scanf()。 因为fgets不会从您的输入中删除空格。 scanf函数仅消耗输入,直到空白为止。 例如,如果输入“ ps -f”,scanf会将此输入用作“ ps”。 如果直接将ps写入shell终端,则可能会遇到与程序异常相同的异常。 您可以将fgets用作流读取器,可以是文件流或标准输入流(stdin)。 我已经编写了解决您问题的代码。 您可以检查使用方法。

/* ----------------------------------------------------------------- */
/* PROGRAM  shell.c                                                  */
/*    This program reads in an input line, parses the input line     */
/* into tokens, and use execvp() to execute the command.             */
/* ----------------------------------------------------------------- */

#include  <stdio.h>
#include  <sys/types.h>

/* ----------------------------------------------------------------- */
/* FUNCTION  parse:                                                  */
/*    This function takes an input line and parse it into tokens.    */
/* It first replaces all white spaces with zeros until it hits a     */
/* non-white space character which indicates the beginning of an     */
/* argument.  It saves the address to argv[], and then skips all     */
/* non-white spaces which constitute the argument.                   */
/* ----------------------------------------------------------------- */

void  parse(char *line, char **argv)
{
     while (*line != '\0') {       /* if not the end of line ....... */ 
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';     /* replace white spaces with 0    */
          *argv++ = line;          /* save the argument position     */
          while (*line != '\0' && *line != ' ' && 
                 *line != '\t' && *line != '\n') 
               line++;             /* skip the argument until ...    */
     }
     *argv = '\0';                 /* mark the end of argument list  */
}

/* ----------------------------------------------------------------- */
/* FUNCTION execute:                                                 */
/*    This function receives a commend line argument list with the   */
/* first one being a file name followed by its arguments.  Then,     */
/* this function forks a child process to execute the command using  */
/* system call execvp().                                             */
/* ----------------------------------------------------------------- */

void  execute(char **argv)
{
     pid_t  pid;
     int    status;

     if ((pid = fork()) < 0) {     /* fork a child process           */
          printf("*** ERROR: forking child process failed\n");
          exit(1);
     }
     else if (pid == 0) {          /* for the child process:         */
          if (execvp(*argv, argv) < 0) {     /* execute the command  */
               printf("*** ERROR: exec failed\n");
               exit(1);
          }
     }
     else {                                  /* for the parent:      */
          while (wait(&status) != pid)       /* wait for completion  */
               ;
     }
}

/* ----------------------------------------------------------------- */
/*                  The main program starts here                     */
/* ----------------------------------------------------------------- */

void  main(void)
{
     char  line[1024];             /* the input line                 */
     char  *argv[64];              /* the command line argument      */

     while (1) {                   /* repeat until done ....         */
          printf("Shell -> ");     /*   display a prompt             */
          fgets(line,1024,stdin);  /*   read in the command line     */
          int i = strlen(line)-1;
          if( line[ i ] == '\n') 
              line[i] = '\0';
          parse(line, argv);       /*   parse the line               */
          if (strcmp(argv[0], "exit") == 0)  /* is it an "exit"?     */
               exit(0);            /*   exit if it is                */
          execute(argv);           /* otherwise, execute the command */
     }
}

产量

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM