0

我为它编写了一些 C 代码,以使用 popen 获取“ls -la”命令的结果并将结果写入 C。代码如下所示:

unsigned int ls(char *destination, const char *username, const char *relative_path)
{
printf("LS IMP\n");
//if(!username || !relative_path) return -1; 
FILE *ls_pipe = NULL;
unsigned long ls_pipe_size = -1;

const char ls_command[] = "ls -la ";
char ls_path[255] = "/home/";   
char ls_full_command[255];

char buffer[255];
bzero(buffer, 255);

char *entries = NULL;   

bzero(ls_full_command, 255);

strcat(ls_path, username);
strcat(ls_path, relative_path);

strcat(ls_full_command, ls_command);
strcat(ls_full_command, ls_path);

printf("AFTER CATS\n");
ls_pipe = popen(ls_full_command, "r");

if(ls_pipe == NULL) return -1;

printf("Pipe ok!");

fseek(ls_pipe, 0, SEEK_END);
ls_pipe_size = ftell(ls_pipe);
rewind(ls_pipe);

printf("Filesize: %lu\n", ls_pipe_size);

int i;

for(i = 0; i < 100; i++)
{
    fread(buffer, 1, 255, ls_pipe);

    printf("%s", buffer);
}

//entries = (char*) malloc(sizeof(char) * ls_pipe_size);
//if(entries == NULL) return -1;
printf("Entries ok!\n");

//if(ls_pipe_size != fread(destination, sizeof(char), ls_pipe_size, ls_pipe))   return -1;

fclose(ls_pipe);
return strlen(destination);

}

问题是管道的大小很大(?),并且在正确结果之后的结果中,三个条目开始像无穷大一样不停地出现。

有没有什么方法可以在不知道结果的确切行数的情况下使用另一个带有 wc -l 的 popen 来读取它?

谢谢

PS当我试图测试出了什么问题时,代码中有一些修改,而 malloc 由于管道的大小而无法正常工作。

4

1 回答 1

1

你不能在管道上寻找——句号。您从中获得的任何价值ftell()都是无关紧要的或错误的。你不能倒回管子,因为你不能在管子上寻找。您只能从管道中读取一次数据。

因此,您需要重新设计代码以读取无限量的数据。

这里有一些可以正常工作的代码——但我需要让它适应 Mac OS X 和我的机器,所以/home/它不使用/Users/, 并且调用ls()使用我的用户名。该代码正确处理充满数据的缓冲区,这些数据不以 null 结尾(为我的bin目录列出了大约 570 行输出)。我将界面ls保持不变,尽管它几乎不使用destination并且返回的长度destination与它正在做的事情无关。它还pclose()用于关闭管道。使用pclose()避免留下僵尸并返回执行程序的退出状态,而fclose()不是。

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static unsigned int ls(char *destination, const char *username, const char *relative_path)
{
    printf("LS IMP\n");
    assert(destination != 0 && username != 0 && relative_path != 0);
    const char ls_command[] = "ls -la ";
    char ls_path[255] = "/Users/";
    char ls_full_command[255];

    snprintf(ls_full_command, sizeof(ls_full_command), "%s %s%s/%s",
             ls_command, ls_path, username, relative_path);

    FILE *ls_pipe = popen(ls_full_command, "r");

    if (ls_pipe == NULL)
        return -1;

    printf("Pipe ok!\n");

    char buffer[255];
    int nbytes;
    while ((nbytes = fread(buffer, 1, 255, ls_pipe)) > 0)
        printf("%.*s", nbytes, buffer);
    putchar('\n');

    printf("Entries ok!\n");
    pclose(ls_pipe);
    return strlen(destination);
}

int main(void)
{
    unsigned int length = ls("/", "jleffler", "bin");
    printf("ls() returned %u\n", length);
    return(0);
}
于 2013-05-06T00:00:47.120 回答