簡體   English   中英

如何處理ls | C中的“管道”命令

[英]How to handle ls | “pipe” command in C

我有一個用C編寫的Shell程序,當我嘗試運行命令“ ls |”時 (只是ls和一個沒有任何內容的管道),我的程序會永遠循環。 您可以忽略modePtr ...該解析器的作用是從用戶輸入中獲取字符串,因此它正在解析命令“ ls |”。 我猜測問題在於事實是沒有空管道命令會陷入無限循環的“情況”? 有什么建議么?

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;
}

如果您嘗試ls | 在普通的shell中,它將在嘗試啟動任何內容之前提示您輸入其余的管道(另一個命令)。 沒有命令讀取輸出的管道是無稽之談。

這個慣用語(在代碼中重復了幾次)被破壞了:

srcPtr++;
while (*srcPtr == ' ' || *srcPtr == '\t' || *srcPtr == '\0')
    srcPtr++;

您不能跳過字符串末尾的空'\\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);

}

...然后,您可以使用strtok()解析每行中的項目,或者,如果您使用“ ls -1”,則每個列表項仍然位於唯一的行上。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM