使用popen(“ls -la”)会产生奇怪的结果

时间:2013-05-05 21:40:33

标签: c linux ipc

我为它编写了一些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来读取结果?

由于

P.S当我试图测试出错的时候代码中有一些修改,并且由于管道的大小,malloc不起作用。

1 个答案:

答案 0 :(得分:1)

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

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

这是一些合理运行的代码 - 但我需要将其改编为Mac OS X和我的机器,因此/home/使用/Users/代替ls(),而bin的调用则使用我的ls用户名。代码正确处理充满数据的缓冲区,这些数据不以null结尾(列出我的destination目录的大约570行输出)。我已将接口保留为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); } 可以避免让僵尸离开并返回执行程序的退出状态,而{{1}}则不会。

{{1}}