所以我正在为我的一个类写一个UNIX shell,基本上我接受一个参数,如果参数有'&'在它结束时,我需要父进程来调用wait();。
我的问题是程序应该接受输入,直到我输入exit,所以一切都在'while'循环中。在我用'&'调用命令之前,事情一直很顺利在它结束时,然后我可以看到父进程结束,然后子进程结束,但后来我不正常接受输入“osh>”。
所以基本上这是我运行简单命令时的正常输出:
osh> ls -l
child:0
a.out main main.cpp main.cpp~
parent: 8695
但是当我用'&'运行命令时最后会发生这种情况:
osh> ls -l &
parent: 27082
osh> child:0
total 44
-rwxr-xr-x 1 myuser users 10368 Mar 1 14:46 a.out
-rwxr-xr-x 1 myuser users 23368 Mar 1 14:00 main
-rw-r--r-- 1 myuser users 1658 Mar 1 14:46 main.cpp
-rw-r--r-- 1 myuser users 1676 Mar 1 14:45 main.cpp~
<cursor is here accepting commands, but no osh> prompt>
如果有人有任何意见或建议,将不胜感激。我觉得这只是一个小错误,但我已经多次通过调试器,找不到任何东西。我只是没有那么多经验。以下是完整的代码:
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
#include <string>
#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
bool status; //status of whether or not an ampersand is in the passed argument
while (should_run) {
int index = 0;
cout << "osh> ";
fflush(stdout);
cin.getline(str, 41);
args[index] = strtok(str, " ");
while (args[index] != NULL) {
index++;
args[index] = strtok(NULL, " ");
}
if (strcmp (args[0], "exit") == 0) //in input is "exit", exit the while loop
break;
if (*args[index - 1] == '&') //check whether to run processes concurrently
status = true;
args[index - 1] = NULL; //remove & to make sure arguments are valid
// (1) fork a child process using fork()
pid_t 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;
if ( execvp (args[0], args) == -1 ) {
perror ("exec");
}
}
// (3) if command didn't included &, parent will invoke wait()
//parent process
if (pid > 0) {
// parent process
if (!status) {
wait(0);
}
cout << "parent: " << pid << endl;
}
}
return 0;
}
编辑:也刚刚意识到在我发布的第二个输出中,它显示“osh&gt;”在父进程之后第二次,不知道如何描述该错误。
答案 0 :(得分:3)
不,您已经在命令提示符下:
osh> child:0
total 44
这是你的命令,提示,osh>
提示。
您的问题在于,您的计算机正在完全按照您要求它执行的操作,而不是您希望它执行的操作。你的代码(它有一个不相关的主要错误,我将在那一刻得到)说不要等到子进程完成,并继续,如果输入&
。
而这正是发生的事情。子进程已启动,您的父进程立即发出下一个osh>
提示符。并且,它在子进程甚至进行了更改以产生任何输出之前就这么快。因此,在osh>
提示符后,子进程的输出将显示在终端上。由于你的父进程已经产生了它的提示,它现在正在等待你的下一个输入,它没有理由不继续等待,在子进程终止后,并完成产生它的输出。
这回答了你的提示发生了什么的问题。你没有解释你预期会发生什么,所以没有什么可以说的;但是如果您想再次重新发出提示,则在子进程终止后,您可以通过正确处理SIGCHLD
信号来实现。有关更多信息,请参阅您的C ++书籍。
就你的无关错误而言,实际上是两个错误:
if (*args[index - 1] == '&')
status = true;
args[index - 1] = NULL; //re
第一个错误:任何以'&'
开头的内容,而不仅仅是“&amp;”它本身将触发后台工作行为。
第二个错误:如果未输入'&'
,此代码仍将删除输入的最后一个单词。这就是为什么当您输入命令ls -l
时,您最终执行ls
,并从第一个命令获得结果输出。