制作简单的Unix shell的问题

时间:2010-04-01 08:55:23

标签: c++ shell

我正在尝试在Unix中创建一个简单的shell。我经常阅读并发现每个人都使用strtok函数。但我想在没有任何特殊功能的情况下这样做。所以我写了代码,但我似乎无法让它工作。我在这里做错了什么?

void process(char**);
int arg_count;
char **splitcommand(char* input)
{
    char temp[81][81] ,*cmdptr[40];
    int k,done=0,no=0,arg_count=0;
    for(int i=0 ; input[i] != '\0' ; i++)
    {
        k=0;
        while(1)
        {
            if(input[i] == ' ')
            {
                arg_count++;
                break;
            }
            if(input[i] == '\0')
            {
                arg_count++;
                done = 1;
                break;
            }
            temp[arg_count][k++] = input[i++];
        }
        temp[arg_count][k++] = '\0';
        if(done == 1)
        {
            break;
        }
    }
    for(int i=0 ; i<arg_count ; i++)
    {
        cmdptr[i] = temp[i];
        cout<<endl;
    }
    cout<<endl;
}


void process(char* cmd[])
{
    int pid = fork();
    if (pid < 0)
    {
        cout << "Fork Failed" << endl;
        exit(-1);
    }
    else if (pid == 0)
    {
        cout<<endl<<"in pid";
        execvp(cmd[0], cmd);
    }
    else
    {
        wait(NULL);
        cout << "Job's Done" << endl;
    }
}


int main()
{
    cout<<"Welcome to shell !!!!!!!!!!!"<<endl;
    char input[81];
    cin.getline(input,81);
    splitcommand(input);
}

5 个答案:

答案 0 :(得分:2)

有几件事:

  • 您不会从splitcommand函数
  • 返回任何内容
  • 你在splitcommand函数中所做的一切都是在局部变量中完成的,所以它(特别是你所创建的字符串)将无法在其结束时存活
  • 附加空终止符的代码是错误的(你把它放到下面的字符串,而不是当前的字符串)
  • 使用固定大小的缓冲区是一个很好的选择;人们喜欢它
  • 请注意,在真正的UNIX shell中,并非每个空格都指定一个参数,并且并非每个参数都由空格指定

我建议你使用字符串和一些(真正的)解析器框架,只要它对你来说不是特别的。

答案 1 :(得分:2)

这几乎可以肯定是作业。除非你被告知,否则没有理由避免库函数。事实上,很可能你被告知要实施strtok。

答案 2 :(得分:1)

strtok并不是一个特殊的函数,因为它的标准函数包括 string.h ,因此没有充分的理由不使用它。

答案 3 :(得分:1)

如果您决定使shell变得更复杂,那么您可以推理使用工具进行词法分析。

例如:

http://en.wikipedia.org/wiki/Flex_lexical_analyser

答案 4 :(得分:0)

问题在于

arg_count++;  

if(input[i] == ' ')if(input[i] == '\0')

当您解析命令行并找到空格或者到达命令行的末尾时,在将\0放在正在读取的命令的末尾之前,您将增加arg_count。

所以改成它:

        if(input[i] == ' ')  
        {  
            // arg_count++;  REMOVE THIS.
            break;  
        }  
        if(input[i] == '\0')  
        {  
            // arg_count++;  REMOVE THIS.
            done = 1;  
            break;  
        }  
        temp[arg_count][k++] = input[i++];  
    }  
    temp[arg_count][k++] = '\0'; // add null-char at the end. 
    arg_count++; // increment should happen here.

更多错误:

  • 你没有从中归来任何东西 splitcommand
  • 你不能只返回cmdptr 因为他们指向本地的char 数组(temp)不会持久存在 函数返回后。所以你会 必须确保数组 temp即使在功能之后仍然存在 通过动态分配来调用 使它成为全球性的。
  • execvp看起来很好的参数 我。其他人请看一看。