我要寫一個需要2個命令及其參數(最多5個)的任務,它會將一個輸出傳遞給另一個。然後它會循環,再次詢問兩個命令,直到輸入quit。分叉和管道C++奇怪輸出
我遇到的問題是,在第二個循環中輸入值後,發生奇怪的事情,例如在輸入第二個命令(都出現在同一行)後立即輸出「Enter Command 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;
}
}
}
}
示例輸出:
[email protected] ~/Documents/Assign10 $ ./z1615629
Command One (or quit): ls -l
Command Two: wc
Command One (or quit): Command One (or quit): quit
示例輸出:
[email protected] ~/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
請將問題解壓縮爲一個自包含的工作示例,以便我們可以看到展示的問題。這裏消化太多了。 – 2012-11-20 21:56:39
使用'execvp()'而不是'execlp()'用switch和'execlp()'來刪除大部分無意義的重複的胡扯。而且,爲了大聲哭泣,不要多次寫這種代碼;使用一個函數來避免重複你自己。 –
我明白,通常我會寫一個函數,但我非常忙,我從來沒有處理過管道。有時候,如果你非常忙於截止日期,你不會認真思考代碼。另外,我很少用C++編寫。無論如何,會嘗試。 – user1840230