[英]Simple Shell with pipes. Unable to count the pipes
I'm tasked with implementing pipes in a simple shell program sshell.c.我的任务是在一个简单的 shell 程序 sshell.c 中实现管道。 Right now, I am just trying to count the number of pipes, but for some reason I am unable to increment my pipe_count despite being able to print it out and see it from the same array args[ARR_SIZE] .现在,我只是想计算管道的数量,但由于某种原因,尽管能够打印出来并从同一个数组args[ARR_SIZE]中查看它,但我无法增加我的 pipe_count。 Each argument is printed as a string so when I type "ls | grep hello", I get "ls", "|", "grep", "hello" all in a row when i run it in a for loop (see #ifdef step1) .每个参数都打印为字符串,所以当我输入“ls | grep hello”时,当我在 for 循环中运行它时,我会连续得到“ls”、“|”、“grep”、“hello” (参见 # ifdef 步骤 1) 。
My question is: How should I set my conditional statement to identify the "|"我的问题是:我应该如何设置我的条件语句来识别“|” symbol?象征?
The program that was given to us does the following:提供给我们的程序执行以下操作:
My implementations are in the #ifdef directives step1 and step2.我的实现在 #ifdef 指令 step1 和 step2 中。 I was trying to break it into small steps.我试图把它分成小步骤。
/*
* This is a simple shell program from
* rik0.altervista.org/snippetss/csimpleshell.html
* It's been modified a bit and comments were added.
*
* But it doesn't allow misdirection, e.g., <, >, >>, or |
* The project is to fix this.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/types.h>
#define BUFFER_SIZE 80
#define ARR_SIZE 80
#define DEBUG 1 /* In case you want debug messages */
#define step1 /*Detect the pipe char*/
//#define step2 /*create pipes*/
//#define step3 /*fork*/
/*Variables for pipes*/
int in[2], out[2], n;
char buf[255];
void error(char *s);
void parse_args(char *buffer, char** args,
size_t args_size, size_t *nargs)
{
char *buf_args[args_size];
char *wbuf = buffer;
buf_args[0]=buffer;
args[0]=buffer; /* First argument */
/*
* The following replaces delimiting characters with '\0'.
* Example: " Aloha World\n" becomes "\0Aloha\0World\0\0"
* Note that the for-loop stops when it finds a '\0' or it
* reaches the end of the buffer.
*/
for(char **cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){
if ((**cp != '\0') && (++cp >= &buf_args[args_size]))
break;
}
/* Copy 'buf_args' into 'args' */
size_t j=0;
for (size_t i=0; buf_args[i]!=NULL; i++){
if(strlen(buf_args[i])>0) /* Store only non-empty tokens */
args[j++]=buf_args[i];
}
*nargs=j;
args[j]=NULL;
}
int main(int argc, char *argv[], char *envp[]){
char buffer[BUFFER_SIZE];
char *args[ARR_SIZE];
int num_pipes = 0;
size_t num_args;
pid_t pid;
while(1){
printf("ee468>> ");
fgets(buffer, BUFFER_SIZE, stdin); /* Read in command line */
parse_args(buffer, args, ARR_SIZE, &num_args);
#ifdef step1 /*Detect pipe symbol in args*/
printf("Printing the args returned from parse_args:\n");
for(int i = 0; i < ARR_SIZE && args[i]!= NULL; i++){
printf("args[%d]: %s\n",i, args[i]);
if(args[i]== "\0|\0" || args[i]=="|"){
num_pipes++;
}
}
printf("There are %d pipes in the buffer.\n",num_pipes);
#endif
if (num_args>0) {
if (!strcmp(args[0], "exit" )) exit(0);
pid = fork();
if (pid){ /* Parent */
#ifdef DEBUG
printf("Waiting for child (%d)\n", pid);
#endif
pid = wait(NULL);
#ifdef DEBUG
printf("Child (%d) finished\n", pid);
#endif
}
else{ /* Child executing the command */
if( execvp(args[0], args)) {
puts(strerror(errno));
exit(127);
}
}
}
}
return 0;
}
void error(char *s)
{
perror(s);
exit(1);
}
if(args[i]== "\0|\0" || args[i]=="|"){
This line does not work as you are only comparing the pointers.此行不起作用,因为您只比较指针。 To compare strings in C you have to use strcmp()
, so it should look something like this:要比较 C 中的字符串,您必须使用strcmp()
,所以它应该看起来像这样:
if (!strcmp(args[i], "|")) {
num_pipes++;
}
Moreover, you shouldn't have a string that contains a NUL character.此外,您不应该有一个包含 NUL 字符的字符串。 C treats the NUL char as the end of the string so everything that follows the NUL char is basically ignored. C 将 NUL 字符视为字符串的结尾,因此 NUL 字符后面的所有内容基本上都被忽略了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.