如何处理ls“;管道;C语言中的命令

如何处理ls“;管道;C语言中的命令,c,shell,pipe,ls,C,Shell,Pipe,Ls,我有一个用C编写的shell程序,当我试图运行命令“ls |”(只有ls和后面没有任何内容的管道)时,我的程序将永远循环。您可以忽略modePtr。。。这个解析器所做的是从用户输入中获取一个字符串,因此它正在解析命令“ls |”,我猜问题在于,没有一个空管道命令会落入“case”中,从而导致无限循环?有什么建议吗 int parse(char *inputString, char *cmdArgv[], char **supplementPtr, int *modePtr) { int cmdA

我有一个用C编写的shell程序,当我试图运行命令“ls |”(只有ls和后面没有任何内容的管道)时,我的程序将永远循环。您可以忽略modePtr。。。这个解析器所做的是从用户输入中获取一个字符串,因此它正在解析命令“ls |”,我猜问题在于,没有一个空管道命令会落入“case”中,从而导致无限循环?有什么建议吗

int parse(char *inputString, char *cmdArgv[], char **supplementPtr, int *modePtr)
{
int cmdArgc = 0, terminate = 0;
char *srcPtr = inputString;
//printf("parse fun%sends", inputString);
while(*srcPtr != '\0' && terminate == 0)
{
    *cmdArgv = srcPtr;
    cmdArgc++;
    //printf("parse fun2%sends", *cmdArgv);
    while(*srcPtr != ' ' && *srcPtr != '\t' && *srcPtr != '\0' && *srcPtr != '\n' && terminate == 0)
    {
        // Handles redirection/pipes
        switch(*srcPtr)
        {
            // Background mode
            case '&':
                *modePtr = BACKGROUND;
                break;
            // Output mode
            case '>':
                *modePtr = OUTPUT_REDIRECTION;
                *cmdArgv = '\0';
                srcPtr++;
                if(*srcPtr == '>')
                {
                    *modePtr = OUTPUT_APP;
                    srcPtr++;
                }
                while(*srcPtr == ' ' || *srcPtr == '\t' || *srcPtr == '\0')
                    srcPtr++;
                *supplementPtr = srcPtr;
                chop(*supplementPtr);
                terminate = 1;
                break;
            // Input mode
            case '<':
                *modePtr = INPUT_REDIRECTION;
                *cmdArgv = '\0';
                srcPtr++;
                while(*srcPtr == ' ' || *srcPtr == '\t' || *srcPtr == '\0')
                    srcPtr++;
                *supplementPtr = srcPtr;
                chop(*supplementPtr);
                terminate = 1;
                break;
            // Pipe mode
            case '|':
                *modePtr = PIPELINE;
                *cmdArgv = '\0';
                srcPtr++;
                while(*srcPtr == ' ' || *srcPtr == '\t' || *srcPtr == '\0')
                    srcPtr++;
                *supplementPtr = srcPtr;
                //chop(*supplementPtr);
                terminate = 1;
                break;
        }
        srcPtr++;
    }
    // Process commands when these occur
    while((*srcPtr == ' ' || *srcPtr == '\t' || *srcPtr == '\n') && terminate == 0)
    {
        *srcPtr = '\0';
        srcPtr++;
    }
    cmdArgv++;
}
/*srcPtr++;
*srcPtr = '\0';
destPtr--;*/
*cmdArgv = '\0';
return cmdArgc;
}
int解析(char*inputString,char*cmdArgv[],char**supplementPtr,int*modePtr)
{
int cmdArgc=0,terminate=0;
char*srcPtr=输入字符串;
//printf(“解析乐趣%sends”,inputString);
while(*srcPtr!='\0'&&terminate==0)
{
*cmdArgv=srcPtr;
cmdArgc++;
//printf(“解析fun2%发送”,*cmdArgv);
而(*srcPtr!='&&*srcPtr!='\t'&&&&*srcPtr!='\0'&&&*srcPtr!='\n'&&terminate==0)
{
//处理重定向/管道
开关(*srcPtr)
{
//背景模式
案例“&”:
*modePtr=背景;
打破
//输出模式
案例“>”:
*modePtr=输出\ U重定向;
*cmdArgv='\0';
srcPtr++;
如果(*srcPtr=='>')
{
*modePtr=输出\应用程序;
srcPtr++;
}
而(*srcPtr=''| |*srcPtr='\t'| |*srcPtr=='\0')
srcPtr++;
*补充PTR=srcPtr;
印章(*补充PTR);
终止=1;
打破
//输入模式

case'如果您在普通shell中尝试
ls |
,它将在尝试启动任何东西之前提示您输入管道的其余部分(另一个命令)。没有读取输出命令的管道是无意义的

这个成语(在代码中重复了好几次)被打破了:

srcPtr++;
while (*srcPtr == ' ' || *srcPtr == '\t' || *srcPtr == '\0')
    srcPtr++;
您不能跳过字符串末尾的null
“\0”
!您会立即陷入“未定义行为”。您需要查看循环逻辑,可能是为了:

srcPtr++;
while (*srcPtr == ' ' || *srcPtr == '\t')
    srcPtr++;
if (*srcPtr == '\0')
    ...no more data in string...

如果您在普通shell中尝试
ls |
,它将在尝试启动任何东西之前提示您输入管道的其余部分(另一个命令)。没有读取输出命令的管道是毫无意义的

这个成语(在代码中重复了好几次)被打破了:

srcPtr++;
while (*srcPtr == ' ' || *srcPtr == '\t' || *srcPtr == '\0')
    srcPtr++;
您不能跳过字符串末尾的null
“\0”
!您会立即陷入“未定义行为”。您需要查看循环逻辑,可能是为了:

srcPtr++;
while (*srcPtr == ' ' || *srcPtr == '\t')
    srcPtr++;
if (*srcPtr == '\0')
    ...no more data in string...

您可能使问题过于复杂。如果您希望程序读取通过管道传输到它的项目列表

#define MAXLINELEN 1000
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) {

    char line[MAXLINELEN];
    FILE *fpin;

    fpin=stdin;

    while(fgets(line,MAXLINELEN,fpin)!=NULL) printf("%s",line);

}
#定义MAXLINELEN 1000
#包括
#包括
int main(int argc,char*argv[]){
字符行[MAXLINELEN];
文件*fpin;
fpin=stdin;
而(fgets(line,MAXLINELEN,fpin)!=NULL)printf(“%s”,line);
}
…然后可以使用strtok()解析每行上的项目,或者如果使用“ls-1”,则每个列表项目都位于唯一的行上


希望这有帮助。

您可能已经将问题复杂化了。如果您希望程序读取通过管道传输到它的列表项

#define MAXLINELEN 1000
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) {

    char line[MAXLINELEN];
    FILE *fpin;

    fpin=stdin;

    while(fgets(line,MAXLINELEN,fpin)!=NULL) printf("%s",line);

}
#定义MAXLINELEN 1000
#包括
#包括
int main(int argc,char*argv[]){
字符行[MAXLINELEN];
文件*fpin;
fpin=stdin;
而(fgets(line,MAXLINELEN,fpin)!=NULL)printf(“%s”,line);
}
…然后可以使用strtok()解析每行上的项目,或者如果使用“ls-1”,则每个列表项目都位于唯一的行上


希望这能有所帮助。

我知道这是胡说八道,但是我如何用这个解析器处理它呢?我知道这是胡说八道,但是我如何用这个解析器处理它呢?我尝试了你的建议,在while循环中使用if语句会更好吗?它没有像你上面建议的那样工作。
if
在循环,因为循环中的
*srcPtr
的唯一值是空的和制表符。您必须考虑提前终止语义;当没有更多的输入可读取,但需要更多的输入时会发生什么情况。您可能会注意到,如果有人键入
ls>
,您的代码就会出现问题;文件名是什么?目前,该文件名是什么与上面相同的循环跳过字符串的结尾,并使用谁知道是什么作为文件名。我尝试了您的建议,是否最好在while循环中使用if语句?它没有按照您上面的建议工作。
if
在循环体中永远不会为真,因为中的
*srcPtr
的唯一值循环为空且为制表符。您必须考虑提前终止语义;当没有更多输入可读取但需要更多输入时会发生什么情况。您可能会注意到,如果有人键入
ls>
,您的代码就会出现问题;文件名是什么?目前,与上述相同的循环跳过字符串末尾并使用谁知道文件名是什么。