C型壳体中的多管道
谁能告诉我这个代码有什么问题吗。我能够成功地写入管道,但当我使用管道输出端作为另一个命令的输入时,无法获得输出。下面是代码C型壳体中的多管道,c,linux,shell,ipc,C,Linux,Shell,Ipc,谁能告诉我这个代码有什么问题吗。我能够成功地写入管道,但当我使用管道输出端作为另一个命令的输入时,无法获得输出。下面是代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> //for pid_t fork() and other system calls #include <signal.h> //for sig
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> //for pid_t fork() and other system calls
#include <signal.h> //for signal()
#include <sys/types.h>
void command_EXECUTER(char *args[]);
void command_HANDLER(char *args[]);
int pipe_EXECUTER(char *args[], int in, int pos);
void shell_INIT(){
int is_interactive = isatty(STDOUT_FILENO);
if(is_interactive){
}
}
int main(int argc, char *argv[], char **envp){
char shell_INPUT[1024];
char *tokens[256];
int tok_counts = 0;
while(1){
memset(shell_INPUT,'\0',sizeof(shell_INPUT));
printf("\n%s@%s: ",getenv("USER"),getenv("SESSION"));
fgets(shell_INPUT,1024,stdin);
if((tokens[0] = strtok(shell_INPUT," \n)\t")) == NULL) continue;
tok_counts = 1;
while((tokens[tok_counts] = strtok(NULL, " \n\t")) != NULL) tok_counts++;
/*
int i=0;
while(tokens[i]){
printf("%s ",tokens[i]);
i++;
}
tokens[tok_counts] = NULL;*/
command_HANDLER(tokens);
}
return 0;
}
int fileIO_EXECUTER(char *args[], int in, int pos){
int fd;
pid_t pid;
if((pid=fork())==0){
switch(pos){
case 0:
dup2(fd, STDOUT_FILENO);
break;
}
}
}
int pipe_EXECUTER(char *args[], int in, int pos){
int fd[2];
pid_t pid;
pipe(fd);
if((pid=fork())==0){
printf("%s %s %s %d\n",args[0],args[1],args[2],pid);
fflush(stdout);
switch(pos){
case 0: dup2(fd[1], STDOUT_FILENO); //first command
//close(fd[1]);
break;
case 1: dup2(in, STDIN_FILENO); //in between command
dup2(fd[1], STDOUT_FILENO);
//close(fd[1]);
break;
case 2: dup2(in, STDIN_FILENO); //last command
//close(fd[1]);
break;
default: printf("wrong input variable\nexiting");
exit(1);
}
if(execvp(args[0],args)==-1) printf("%s: command not found",args[0]); fflush(stdout); kill(getpid(),SIGTERM);
}else if(pid<0){
printf("couldn't create child");
exit(1);
}else{
wait(pid);
}
return fd[0];
}
void command_EXECUTER(char *args[]){
pid_t pid;
if((pid=fork())<0){
printf("couldn't create the child");
exit(1);
}
else if(pid==0){
if((execvp(args[0],args))==-1) printf("%s: command not found",args[0]); fflush(stdout); kill(getpid(),SIGTERM);
}
else wait(pid);
}
void command_HANDLER(char *args[]){
int i=0;
int j=0;
char spec_chars[100];
while(args[i]){
if((strcmp(args[i],">")==0) || (strcmp(args[i],"<")==0) || (strcmp(args[i],"|")==0) || (strcmp(args[i],"&")==0) || (strcmp(args[i],"$")==0)){
spec_chars[j] = *args[i];
j++;
}
i++;
}
if(j==0){
if(strcmp(args[0],"exit")==0) exit(0);
else if(strcmp(args[0],"clear")==0) system("clear");
else command_EXECUTER(args);
}
else{
int in = 0;
int h = 0;
int pos=0;
char data[1024];
int k=i;
i = 0;
while(args[i]){
if(strcmp(args[i],"|")==0){
args[i] = (char *)NULL;
in = pipe_EXECUTER(args,in,pos);
int n = read(in,data,sizeof(data));
printf("%s %d\n",data,n);
fflush(stdout);
args = args+i+1;
//printf("%s something %s",args[0],args[1]);
pos = 1;
i=0;
}else if(strcmp(args[i],"<")==0){
}else if(strcmp(args[i],">")==0){
}else if(strcmp(args[i],"&")==0){
}
else{
i++;
}
}
in = pipe_EXECUTER(args,in,2);
}
}
#包括
#包括
#包括
#包含//用于pid\u t fork()和其他系统调用
#包括//用于信号()
#包括
void命令执行器(char*args[]);
void命令处理程序(char*args[]);
int pipe_执行器(字符*参数[],int in,int pos);
void shell_INIT(){
int is_interactive=isatty(标准文件号);
如果(是交互式的){
}
}
int main(int argc,char*argv[],char**envp){
字符shell_输入[1024];
字符*标记[256];
int tok_计数=0;
而(1){
memset(shell_输入,'\0',sizeof(shell_输入));
printf(“\n%s@%s:”,getenv(“用户”),getenv(“会话”);
fgets(外壳输入,1024,标准输入);
如果((标记[0]=strtok(shell\u输入,“\n\t”)==空)继续;
tok_计数=1;
而((令牌[tok_计数]=strtok(NULL,“\n\t”))!=NULL)tok_计数++;
/*
int i=0;
while(代币[i]){
printf(“%s”,代币[i]);
i++;
}
令牌[tok_计数]=空*/
命令处理程序(令牌);
}
返回0;
}
int fileIO_执行器(字符*参数[],int-in,int-pos){
int-fd;
pid_t pid;
如果((pid=fork())==0){
开关(pos){
案例0:
dup2(fd,标准文件号);
打破
}
}
}
int pipe_执行器(字符*参数[],int in,int pos){
int-fd[2];
pid_t pid;
管道(fd);
如果((pid=fork())==0){
printf(“%s%s%s%d\n”,参数[0],参数[1],参数[2],pid);
fflush(stdout);
开关(pos){
案例0:dup2(fd[1],STDOUT_FILENO);//第一个命令
//关闭(fd[1]);
打破
案例1:dup2(in,STDIN_FILENO);//中间命令
dup2(fd[1],标准文件号);
//关闭(fd[1]);
打破
案例2:dup2(in,STDIN_FILENO);//最后一个命令
//关闭(fd[1]);
打破
默认值:printf(“错误的输入变量\n输入”);
出口(1);
}
if(execvp(args[0],args)==-1)printf(“%s:未找到命令”,args[0]);fflush(stdout);kill(getpid(),SIGTERM);
}否则,如果(pid
“in”描述符将包含ls,但当相同的输出
通过“排序”访问,它挂在那里
这是由于没有在父进程中关闭管道的写入端而导致的,因为排序
会自然地等待,直到所有引用写入端的文件描述符都关闭,以确保不再有输入到达。因此,在管道执行器()
中,必须调用关闭(fd[1])
在返回fd[0]之前;
当然还有调试代码
int n = read(in,data,sizeof(data));
printf("%s %d\n",data,n);
在
命令中,必须删除HANDLER()
,为了不使用排序的输入(gcc-Wall-Wextra-g
),请使用所有警告和调试信息(gcc-Wall-Wextra-g
)进行编译,然后使用调试器(gdb
);还要进行故障测试(并在出现故障时使用peror
)每一个也考虑使用<代码> Struts <代码> Valgnnd/Cuth>实际上我刚开始用这个,不知道如何使用GDB或其他调试工具……如果你可以帮助……谢谢,你需要学习<代码> GDB 。这是一个有用的技能很多年!l gdb、strace和valgrind但仍然没有运气:(有些bug需要几周才能被发现。祝你好运!不要放弃。休息一下,然后继续寻找你的bug。不要忘记阅读你正在使用的每个系统调用的文档。特别是,你使用的dup2
是错误的:你没有处理dup2
的故障。另外,在fork
之前调用fflush