Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我的代码中有一个奇怪的bug导致了一些奇怪的结果,我相信它';那是因为我用叉子_C++_Bash - Fatal编程技术网

C++ 我的代码中有一个奇怪的bug导致了一些奇怪的结果,我相信它';那是因为我用叉子

C++ 我的代码中有一个奇怪的bug导致了一些奇怪的结果,我相信它';那是因为我用叉子,c++,bash,C++,Bash,不同类型的输入会产生一些不同的奇怪结果。首先,我正在构建一个简单的linux shell,下面我将展示一些I/o示例 $ $ $ $ ls -l / $ $ exit 所以你可能首先注意到的是双美元。每当我在提示符中输入了某些内容而不是将其留空时,就会发生这种情况。其次,它似乎已正确退出,因为它将控制权返回到我的终端。。。还是这样?我真的不知道,但当我在我的终端,如果我只需按回车键,这个弹出在我的终端 finn-and-jake@CandyKingom:~/Desktop/OS/hw2$

不同类型的输入会产生一些不同的奇怪结果。首先,我正在构建一个简单的linux shell,下面我将展示一些I/o示例

$ 
$ 
$ 
$ ls -l /
$ $ exit
所以你可能首先注意到的是双美元。每当我在提示符中输入了某些内容而不是将其留空时,就会发生这种情况。其次,它似乎已正确退出,因为它将控制权返回到我的终端。。。还是这样?我真的不知道,但当我在我的终端,如果我只需按回车键,这个弹出在我的终端

finn-and-jake@CandyKingom:~/Desktop/OS/hw2$ terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at
我不是百分之百地知道是什么原因造成的,也不是如何修复的,但我有一种预感,它与fork有关,我相信这也是我额外花费美元的原因。还有一个问题,当我像上面那样输入时,但是在初始和退出之间有一些空输入,这导致程序没有完全关闭。下面提供了一个例子

$ 
$ 
$ ls -l /
$ $ 
$ 
$ 
$ 
$  
$ 
$ 
$ exit

$ exit
最后,还有一个问题,我不确定是什么原因导致了它,程序运行在一个无限循环中,我无法强制退出,它导致我的操作系统崩溃(Ubuntu 14.04)

为了尽量减少代码,我只包括我怀疑是导致这种情况的方法。如果有任何超过这一要求,我将包括在编辑它

void Shell::interpreteInput() {
        if (commandQueue.empty()) {
                return;
        };

        if (commandQueue.at(0) == "exit") {
                exit = true;
                return;
        };

        pid_t pid = fork();
        if (pid < 0) {
                cerr << "Fork unsuccessful\n";
                return;
        };
        if (commandQueue.size() >= 3 && commandQueue.at(commandQueue.size() - 2) == ">") {
                //commandQueue.at(commandQueue.size() - 1) is fileName          open


                //commandQueue.at(0) is name of program to run                  exec 
                //remaining substrings are args
        };

        //commandQueue.at(0) is name of program to run                          exec
        // remaining substrings are args

};
void Shell::解释器输入(){
if(commandQueue.empty()){
返回;
};
if(commandQueue.at(0)=“退出”){
退出=真;
返回;
};
pid_t pid=fork();
if(pid<0){
cerr=3&&commandQueue.at(commandQueue.size()-2)=“>”){
//commandQueue.at(commandQueue.size()-1)是文件名打开的
//commandQueue.at(0)是要运行exec的程序的名称
//剩下的子字符串是args
};
//commandQueue.at(0)是要运行exec的程序的名称
//剩下的子字符串是args
};
编辑(对注释中的第一个问题的回答):在子进程中,执行给定的程序,并向其传递给定的参数(如果有)。如果该程序是一个空名称(即,它不包含任何斜杠),则搜索可执行文件的路径。如果该行具有表单1(我的第四个if语句),则输出将重定向到打开的位置(创建或覆盖)具有给定路径的文件,并将程序的输出重定向到该文件。(请参阅下面的详细说明。)

•如果要重定向输出,但无法打开文件,则显示错误消息并返回步骤1


•如果给定程序无法执行(exec失败),则显示错误消息并返回到步骤1。

您需要确保在父进程中使用类似于
waitpid()
的函数或相关等待函数之一。当
fork()
成功返回时(非-1),有两个进程正在运行。父进程将返回子进程的实际PID。子进程将获得返回值0。因此,您需要如下代码:

pid_t pid = fork();
if (pid == -1) {
   // handle error
} else if (pid == 0) {
   // do child process stuff
} else {
   // do parent process stuff
   int status, rc;
   do {
       rc = waitpid(pid, &status, 0);
       // handle rc value from waitpid
   } while (!WIFEXITED(status));
}

您需要确保正在父进程中使用类似于
waitpid()
的函数或一个相关的等待函数。当
fork()
成功返回时(不是-1),有两个进程正在运行。父进程将返回子进程的实际PID。子进程将获得返回值0。因此,您需要如下代码:

pid_t pid = fork();
if (pid == -1) {
   // handle error
} else if (pid == 0) {
   // do child process stuff
} else {
   // do parent process stuff
   int status, rc;
   do {
       rc = waitpid(pid, &status, 0);
       // handle rc value from waitpid
   } while (!WIFEXITED(status));
}
fork()
之后,会检查fork错误,但在其他情况下,父进程和子进程都会在之后执行相同的操作。您可能希望分离代码路径:父进程执行一项操作,子进程执行另一项操作

传统上,shell父进程等待子进程完成,除非有一个
&
指示父进程不等待。然后子进程将命令行和
exec
的命令集在一起。

fork()之后
,有一个fork错误检查,但在其他情况下,父进程和子进程随后都会执行相同的操作。您可能希望分离代码路径:父进程执行一项操作,子进程执行另一项操作


传统上,shell父进程等待子进程完成,除非有
&
指示父进程不等待。然后子进程将命令行和
exec
的命令集中在一起.

您是否在等待分叉进程返回父进程?您的代码中不清楚您是否在等待分叉进程。您需要为父进程和子进程设置单独的代码路径。父进程应该等到所有子进程完成后再退出。@KurtStutsman问得好,我自己也不太确定我对所有这些都很陌生。fo下面是给我的指令……实际上我会将其编辑。@πάνταῥεῖ 这将需要更多的检查,以查看父进程的pid>0,子进程的pid==0是否正确?然后在子进程中使用execvp函数使输入执行?是否正在等待分叉进程返回父进程?如果是,代码中不清楚。需要为父进程和子进程提供单独的代码路径。T父进程应该等到所有子进程完成后再退出。@KurtStutsman问得好,我自己也不太清楚我对这一切都很陌生。下面是给我的说明……实际上我会将其编辑。@πάνταῥεῖ 这将是更多的检查,以查看父对象的pid>0,子对象的pid==0是否正确?然后在子对象中使用execvp函数来执行输入?谢谢!您能解释一下rc值是什么吗?这是典型的C系统调用errno return。描述了函数的返回代码。正如@wallyk在他的ans中指出的那样wer,
waitpid()
部分仅对