修复我的shell程序的控制台输出

时间:2014-04-29 05:29:04

标签: c++ shell asynchronous

我正在编写一个程序,它被设计为一个shell,它调用接收来自用户的输入并调用子进程来执行命令。程序的输出应该在每行的开头包含一个shell提示符,它显示命令的发出次数,如下所示:

bashell[1]: ls    
bashell  bashell.cpp  bashell.cpp~  myshell.c~
bashell[2]: ls
bashell  bashell.cpp  bashell.cpp~  myshell.c~

不幸的是,我在格式化输出时遇到了严重问题,所以它看起来很不错。我想这可能是由于我的程序的异步性质。我得到这样的东西:

bashell[1]: ls
bashell[2]: 
bashell  bashell.cpp  bashell.cpp~  myshell.c~
ls
bashell[3]: 
bashell  bashell.cpp  bashell.cpp~  myshell.c~
ls
bashell[4]: 
bashell  bashell.cpp  bashell.cpp~  myshell.c~
ls
bashell[5]: 
bashell  bashell.cpp  bashell.cpp~  myshell.c~

ls是我的输入,其余来自shell。正如您所看到的,当我输入ls时,shell提示符甚至没有出现,它只是空白,并且在我输入命令后出现shell提示符。

这是我的相关代码,在调用setup(inputBuffer,args和& background)获取inputBuffer和命令参数之前,我调用printShellPrompt()来打印shell提示符。

int main(void)
{
    char inputBuffer[MAX_LINE];      /* buffer to hold the command entered */
    int background;              /* equals 1 if a command is followed by '&' */
    char *args[(MAX_LINE/2)+1];  /* command line (of 80) has max of 40 arguments */
    pid_t pid;

    // startup greeting
    cout << "Welcome to bashell. My pid is " << getpid() << "." << endl; 

    int commandCount = 1; // for counting the number of commands so far

    while (1){            /* Program terminates normally inside setup */
       background = 0;
      // printf("bashell[%d]: ", commandCount);
      // fflush(stdout); 
      // cout << "bashell[" << commandCount << "]: ";
      // cout.flush();
       printShellPrompt(commandCount);
       setup(inputBuffer,args,&background);       /* get next command */

       // if built-in command, handle internally
       if (strcmp(args[0], "whisper") == 0)
       {
         string whisperedPhrase;
         for (int i = 1; i < arrayCount(args); i++)
     {
           // change from uppercase to lowercase for each char in the token and concatenate
           // it to the final whispered phrase
           char letter = 'a';
       for (int f = 0; f < strlen(args[i]); f++)
           {
             letter = tolower(args[i][f]);
             whisperedPhrase.push_back(letter);
           }
           whisperedPhrase.push_back(' '); 
     }
         cout << whisperedPhrase;
         cout << endl;
       }
       else if (strcmp(args[0], "exit") == 0)
       {
         char command[] = "ps -p ";
         char pid[10];
         snprintf(pid, 10, "%d", (int)getpid());
         strcat(command, pid);
         strcat(command, " -o pid,ppid,pcpu,pmem,etime,user,command");
         system(command);
         exit(1); 
       }
       else
       {
         /*
         (1) if not, fork a child process using fork()
         (2) the child process will invoke execvp()
         (3) if background == 0, the parent will wait,
            otherwise returns to the setup() function. */

         // seperate filename and arguments given by user
         char *fileToRun = args[0];

         // fork a child process
         pid = fork();

         if (pid < 0)
         {
           cerr << "Fork failed";
       return 1;
         }
         else if (pid == 0) // child process
         { 
           cout << endl;
           execvp(fileToRun, args);
         }
         else if (pid > 0 && background == 1) // parent process
         {
           // parent will wait for child to complete
           wait();
         }
       }

      commandCount++; // increment the command count
    }
}

任何想法都将不胜感激!

0 个答案:

没有答案