1

制作一个非常基本的shell作为分配。假设我有一个字符串"ls a b c | grep a"

我怎样才能得到这样的东西

commands[0][0] = "ls"
commands[0][2] = "a"
commands[0][2] = "b"
commands[0][3] = "c"
commands[0][4] = NULL

commands[1][0] = "grep"
commands[1][1] = "a"
commands[1][2] = NULL

首先拆分"|",然后在空格上进一步拆分,因此能够执行execvp(commands[0][0], commands[0])

我可以很好地进行单分裂,但是这种双分裂有点麻烦

4

2 回答 2

3

我没有用 execvp 测试过

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define WHITESPACE 1
#define ARGUMENT 2
#define COMMAND 3
void process_command(const char *string)
{
   char *argument = (char *) 0;
   char *args[100];
   char *const * commands[10];
   int commands_index = 0;
   int char_index = 0;
   int args_index = 0;
   int state = WHITESPACE;
   commands[commands_index] = &args[args_index];
   for (const char *p = string; *p != '\0'; p++)
   {
      if ( *p != ' ' )
      {
         if ( *p == '|' )
         {
            if ( state == ARGUMENT)
            {
               argument[char_index] = '\0';
               char_index = 0;
            }
            state = COMMAND;
            args[args_index] = 0;
            args_index++;
            commands_index++;
            commands[commands_index] = &args[args_index];
         }
         else
         {
            if ( state != ARGUMENT )
            {
               argument = malloc(100);
               args[args_index] = argument;
               args_index++;
               state = ARGUMENT;
            }
            argument[char_index] = *p;
            char_index++;
         }
      }
      else 
      {
         if ( state == ARGUMENT)
         {
            argument[char_index] = '\0';
            char_index = 0;
         }
         state = WHITESPACE;
      }
   }
   argument[char_index] = '\0';
   args[args_index] = 0;
   //execvp(commands[0][0],commands[0]);
   //execvp(commands[1][0],commands[1]);

   for (int i = 0; i <= commands_index; i++)
   {
      int j = 0;
      for (; commands[i][j] != 0;j++)
      {
         printf("commands[%d][%d] = \"%s\"\n",i,j,commands[i][j]);
      }
      printf("commands[%d][%d] = NULL\n",i,j);
   }
   printf("\n");
}



int main(void)
{

   const char *string1 = "ls a b c | grep a";
   const char *string2 = "ls -al|grep txt";
   const char *string3 = "cat file.txt | grep hello |more";
   process_command(string1);
   process_command(string2);
   process_command(string3);
}

输出:

commands[0][0] = "ls"
commands[0][1] = "a"
commands[0][2] = "b"
commands[0][3] = "c"
commands[0][4] = NULL
commands[1][0] = "grep"
commands[1][1] = "a"
commands[1][2] = NULL

commands[0][0] = "ls"
commands[0][1] = "-al"
commands[0][2] = NULL
commands[1][0] = "grep"
commands[1][1] = "txt"
commands[1][2] = NULL

commands[0][0] = "cat"
commands[0][1] = "file.txt"
commands[0][2] = NULL
commands[1][0] = "grep"
commands[1][1] = "hello"
commands[1][2] = NULL
commands[2][0] = "more"
commands[2][1] = NULL
于 2012-08-19T15:13:58.643 回答
1

您可以尝试使用strtok_r拆分字符串并获取令牌并构建预期的命令行/字符串数组。

于 2012-08-19T12:30:58.737 回答