我目前正致力于使用Linux系统调用的microshell的实现。我的大部分代码都在那里工作,但是当我尝试将一个命令传递给另一个时,我遇到了一个问题。当我输入more myfile || grep Dog
时,我应该将Dog
显示回来,但我没有显示任何内容,当我尝试管道时,这适用于任何事情。像cat myfile
这样的单个命令工作得很好。我只能假设我目前正在尝试使用pipe
的方式有问题,但我似乎无法弄清楚是什么导致了它。
修改:||
实际上没有进行管道操作,在第一个while
循环中搜索||
的用户输入以指示用户想要执行管。然后从那里开始从变量mainPipe
创建管道。
以下是我的名为myfile
的文件。
Nope
Illinois
USA
Dog
这是我的代码,
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <sys/utsname.h>
#include <unistd.h>
using namespace std;
#define BUFFER_SIZE 1024
#define PIPE_SIZE 2
void const firstCommandWork(int _pipe[], char * command[], const bool pipeExists);
void const secondCommandWork(int _pipe[], char * command2[]);
int main() {
char *userCommand[BUFFER_SIZE], //char array ptrs that will hold the user desired command
*userCommand2[BUFFER_SIZE], //Note to self: maybe NULL first few to clear out space.
buffer[BUFFER_SIZE]; //buffer that will hold user input
int status, //status of the child process in it's parents process
status2;
int mainPipe[PIPE_SIZE]; //pipe variable
pid_t fork1, //fork variables
fork2;
cout << "480shell>"; //shell header
while (fgets(buffer, BUFFER_SIZE, stdin) != NULL) { //continue to get input from user until none is entered
bool userWantsPipe = false; //variable that will be set to true if the user wishes to use pipe command
buffer[strlen(buffer) -1] = 0; //remove last character in buffer
int tokenIndex = 0; //used to seperate tokens
char *bufferPtr; //char array to hold saved token made by strok
bufferPtr = strtok(buffer, " "); //gets first command from buffer up to a white space and saves it in bufferPtr
while(bufferPtr != NULL) { //continue as long as there's something in the bufferPtr
if( (strcmp( bufferPtr, "q" ) == 0) || (strcmp( bufferPtr, "quit" ) == 0) ) { //if user entered "q" or "quit, exit program
cout << "Exiting.." << endl << endl;
return 0;
}
if(strcmp( bufferPtr, "||" ) == 0) { //if user entered "||" (meaning they wish to use pipe)
userWantsPipe = true; //set userWantsPipe to true
bufferPtr = strtok(NULL, " ");
}
if(!userWantsPipe) { //if user has not entered "||" (meaning they do not wish to pipe)
userCommand[tokenIndex] = bufferPtr; //grab first command (in the bufferPtr) and store it in the first user command variable @ tokenIndex (0)
bufferPtr = strtok(NULL, " ");
tokenIndex++; //add one to tokenIndex, to represent one command already gotten
}
else { //user has entered "||" (meaning they wish to pipe)
userCommand2[tokenIndex] = bufferPtr; //grab first command (in the bufferPtr) and store it in the first user command variable @ tokenIndex (0)
bufferPtr = strtok(NULL, " ");
tokenIndex++; //add one to tokenIndex, to represent one command already gotten
int val = pipe(mainPipe); //create pipe from pipe variable
if(val == -1) {
cout << "Failed: Pipe. Exiting..." << endl;
}
}
}
fork1 = fork(); //create first fork
if(fork1 < 0) { //first fork has failed, exit program
cerr << "Failed: First Fork. Exiting..." << endl;
return -1;
}
if(fork1 == 0) { //child process of first fork
firstCommandWork(mainPipe, userCommand, userWantsPipe);
}
if(userWantsPipe) { //if the user used the pipe command
fork2 = fork(); //create second fork
if(fork2 == 0) { //child process of second fork
secondCommandWork(mainPipe, userCommand2);
}
if(fork2 < 0) { //second fork has failed, exit program
cerr << "Failed: Second Fork. Exiting..." << endl << endl;
return -1;
}
}
if(userWantsPipe) { //if the user used the pipe command
close(mainPipe[0]); //close ends of the pipe
close(mainPipe[1]);
}
fork1 = waitpid(fork1, &status, 0); //wait for first child to execute
if(fork1 < 0) { //waiting on first child to finish has failed, exit program
cerr << "Failed: Waiting First Child. Exiting..." << endl;
return -1;
}
if(userWantsPipe) { //if the user used the pipe command
fork2 = waitpid(fork2, &status2, 0); //wait for second child to execute
if (fork2 < 0) { //waiting on second child to finish has failed, exit program
cerr << "Failed: Waiting Second Child. Exiting..." << endl << endl;
return -1;
}
}
cout << "480shell>"; //shell header
}
return 0;
}
/*********************************************************
void const firstCommandWork(int [], char* [], const bool)
returns: nothing
arguments: 1) a int array representing a pipe (_pipe)
2) a ptr to a char array (command), holds the commands entered by the user
3) a constant bool (pipeExists), holds true if user used pipe command
otherwise holds false
use: ** used to execute the first command entered by user **
first, if the user wanted to use the pipe command (pipeExists will be true in this case)
we will first call dup2() on the pipe (_pipe) to create copy of the file descriptor
then we will close the end of the pipe (_pipe)
second, then we will execute the command @ location 0 (this will be the first command) in command array
if the command has failed, display a message, exit with -1
*********************************************************/
void const firstCommandWork(int _pipe[], char *command[], const bool pipeExists) {
if(pipeExists) {
dup2(_pipe[1], 1);
close(_pipe[0]);
}
int val = execvp(command[0], command); //store value of whether or not command could execute
if(val < 0) { //couldn't execute command, display message, exit with a value of -1
cerr << "Error: Could Not Execute First Command!" << endl;
exit(-1);
}
}
/*********************************************************
void const secondCommandWork(int [], char* [])
returns: nothing
arguments: 1) a int array representing a pipe (_pipe)
2) a ptr to a char array (command2), holds the commands entered by the user
use: ** used to execute the second command entered by user **
first, we will first call dup2() on the pipe (_pipe) to create copy of the file descriptor
then we will close the end of the pipe (_pipe)
second, then we will execute the command @ location 0 (this will be the second command) in command2 array
if the command has failed, display a message, exit with -1
*********************************************************/
void const secondCommandWork(int _pipe[], char *command2[]) {
dup2(_pipe[0], 0);
close(_pipe[1]);
int val = execvp(command2[0], command2); //store value of whether or not command could execute
if(val < 0) { //couldn't execute command, display message, exit with a value of -1
cerr << "Error: Could Not Execute Second Command!" << endl;
exit(-1);
}
}
答案 0 :(得分:0)
在第二个 constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit() {
this.activatedRoute.queryParams.subscribe((data) => {
console.log(data);
});
}
循环中向tokenIndex = 0;
正文添加了else
。修复问题。