【问题标题】:Trying to fork a process, first command works but second always gives an error尝试分叉一个进程,第一个命令有效,但第二个总是出错
【发布时间】:2017-02-25 23:34:08
【问题描述】:

所以目前我正在创建一个 shell 接口,它接受用户命令,然后在单独的进程中执行每个命令。我花了一点时间才将输入正确输入到字符数组中。 (必须解析它并划分每个输入,即args [0] = ls,args [1] = -l)。我很确定我做的那部分是对的,但我认为这就是给我带来问题的原因。

所以在我解析输入之后,我创建了一个子进程来使用 execvp 系统调用来执行参数。在我的父进程中,我有一个条件语句,如果命令的最后一部分中有一个 & 符号,则调用 Wait() 函数。

所以我面临的问题是,当我执行此代码时,我能够正确执行第一个命令,但无论第二个命令是什么,我都会收到错误消息。我认为这与事后不清除数组有关,但很难缩小这个问题的范围。任何帮助将不胜感激。

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

#define MAX_LINE 80 //the maximum length command

using namespace std;

int main()
{
  char* args[MAX_LINE/2 + 1]; //command line arguments
  char str[41]; //intitialize string for input
  int should_run = 1; //flag to determine when to exit program
  int index = 0;
  pid_t pid; //process id

  while (should_run) {
    cout << "prompt> ";
    fflush(stdout);

    cin.getline(str, 41);

    args[index] = strtok(str, " ");

    while (args[index] != NULL) {
      // test      cout << args[index] << endl;
      index++;
      args[index] = strtok(NULL, " ");
    }

    args[index + 1] = NULL;

    if (strcmp (args[0], "exit") == 0) //in input is "exit", exit the while loop
      break;

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

    if (pid < 0) { //error handling
      perror("Fork Failed.");
      break;
    }
    // (2) the child process will invoke execvp()
    if (pid == 0) {
      //child process
      cout << "child:" << pid << endl;
      execvp (args[0], args);
    }

    // (3) if command didn't included &, parent will invoke wait()
    //parent process
    if (pid > 0)
      {
        // parent process
        if (strcmp (args[index], "&") == 0) {
          wait(0);
          cout << "parent: " << pid << endl;
        }
      }
  }
  return 0;
}

【问题讨论】:

  • 这个bug非常明显。而且我敢肯定,一旦您使用调试器单步执行代码,一次一行,检查所有变量的值,您将能够自己找出错误。了解如何使用调试器是每个 C++ 开发人员必备的技能。免费线索:在循环的第二次迭代中,使用调试器显示index 的值。
  • @SamVarshavchik 你能推荐一个吗?我还没有学会如何正确使用它。现在是开始的好时机。
  • 在 Linux 和 Unix 上,gdb 占据主导地位。值得注意的是,只有一个调试器。
  • @SamVarshavchik 我的索引应该已经在 while 循环中初始化了吧?
  • 差不多。

标签: c++ shell unix process fork


【解决方案1】:

您在解析第二个和后续命令时忘记将 index 重新初始化为 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多