我要编写一个包含 2 个命令及其参数(最多 5 个)的作业,它将通过管道将一个命令的输出传递给另一个。然后它将循环,再次询问两个命令,直到输入退出。
我遇到的问题是,在第二个循环中输入值后,会发生奇怪的事情,例如在输入第二个命令后立即输出“输入命令 1”(两者都出现在同一行)。我还注意到例如输入 ls -l 然后 cat 可以工作,但是输入 ls -l 然后 wc 会导致问题。有人介意看看并可能帮助我吗?我整天都在努力,我还有一个多小时的时间来完成它。
旁注:是的,我意识到执行命令设置有点愚蠢,但我没有时间,没有时间摆弄它。有用。
#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sstream>
using namespace std;
int main(){
//Our imput strings that the user enters.
string input1;
string input2;
//Temporary string.
string s;
//Array to hold the items passed in.
string arg1[6];
string arg2[6];
//A count of how many items they passed in.
int carg1;
int carg2;
//Loop until quit.
while(true){
//Set all our values to empty/zero
carg1 = 0;
carg2 = 0;
input1.clear();
input2.clear();
//Prompt for first command.
while(input1.empty()){
cout << "Command One (or quit): ";
getline(cin, input1);
}
//Split the string by the space to get the pieces of the command.
istringstream iss1(input1);
while (getline(iss1, s, ' ')) {
arg1[carg1] = s;
carg1++;
}
//Check if command is quit and exit if true.
if(arg1[0].compare("quit") == 0){
return 0;
}
//Prompt for command 2.
while(input2.empty()){
cout << "Command Two: ";
cin >> input2;
}
//Once again, split based on spaces.
istringstream iss2(input2);
while (getline(iss2, s, ' ')) {
//arg2.push_front(s);
arg2[carg2] = s;
carg2++;
}
//Initialize the pipe.
int pipefd[2];
if(pipe(pipefd) == -1){
perror("Pipe");
exit(EXIT_FAILURE);
}
//Create the fork to two processes.
int pid = fork();
//Switch to check for parent and child.
switch(pid){
case 0: //Child process
//Close the read pipe and standard input.
close(pipefd[0]);
close(1);
//Copy data
dup(pipefd[1]);
//Close other end of the pipe
close(pipefd[1]);
//Execute the first command. Based on how many params, call different ones.
switch(carg1){
case 1:
execlp(arg1[0].c_str(), arg1[0].c_str(), (char*)NULL);
break;
case 2:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), (char*)NULL);
break;
case 3:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), (char*)NULL);
break;
case 4:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), arg1[3].c_str(), (char*)NULL);
break;
case 5:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), arg1[3].c_str(), arg1[4].c_str(), (char*)NULL);
break;
case 6:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), arg1[3].c_str(), arg1[4].c_str(), arg1[5].c_str(), (char*)NULL);
break;
case 7:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), arg1[3].c_str(), arg1[4].c_str(), arg1[5].c_str(), arg1[6].c_str(), (char*)NULL);
break;
}
return 0;
case -1: //Error
perror("fork");
exit(EXIT_FAILURE);
default: //Parent Process
//Wait for initial command to execute.
wait(&pid);
//Fork into two processes.
int pid2 = fork();
//Switch based on child and parent.
switch(pid2){
case 0: //Child process
//Close write end of pipe and standard output.
close(pipefd[1]);
close(0);
//Duplicate to standard input
dup(pipefd[0]);
//Close read end.
close(pipefd[0]);
//Execute proper command based on params
switch(carg2){
case 1:
execlp(arg2[0].c_str(), arg2[0].c_str(), (char*)NULL);
break;
case 2:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), (char*)NULL);
break;
case 3:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), (char*)NULL);
break;
case 4:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), arg2[3].c_str(), (char*)NULL);
break;
case 5:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), arg2[3].c_str(), arg2[4].c_str(), (char*)NULL);
break;
case 6:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), arg2[3].c_str(), arg2[4].c_str(), arg2[5].c_str(), (char*)NULL);
break;
case 7:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), arg2[3].c_str(), arg2[4].c_str(), arg2[5].c_str(), arg2[6].c_str(), (char*)NULL);
break;
}
return 0;
case -1: //Error
perror("fork");
exit(EXIT_FAILURE);
default: //Parent Process
//wait(&pid2);
break;
}
}
}
}
示例输出:
nick@nick-VirtualBox ~/Documents/Assign10 $ ./z1615629
Command One (or quit): ls -l
Command Two: wc
Command One (or quit): Command One (or quit): quit
示例输出:
nick@nick-VirtualBox ~/Documents/Assign10 $ ./z1615629
Command One (or quit): ls -l
Command Two: cat
Command One (or quit): Command One (or quit):
total 32
-rwxr-xr-x 1 nick nick 13358 Nov 20 15:46 z1615629
-rw-r--r-- 1 nick nick 4544 Nov 20 15:46 z1615629.cxx
-rw-r--r-- 1 nick nick 8104 Nov 20 15:46 z1615629.o