我为它编写了一些 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 没有工作。
最佳答案
您不能在管道上搜索 — 句号。您从 ftell()
返回的任何值都是无关紧要的或错误的。您无法倒带管道,因为您无法在管道上搜索。您只能从管道中读取一次数据。
因此,您需要重新设计代码以读取无限量的数据。
这里有一些合理的工作代码——但我需要使它适应 Mac OS X 和我的机器,所以它使用 /Users/
而不是 /home/
,并且对 ls()
的调用使用了我的用户名。该代码正确地处理了充满不以空结尾的数据的缓冲区(为我的 bin
目录列出了大约 570 行输出)。我保留了 ls
的接口(interface)不变,尽管它几乎不使用 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);
}
关于c - 使用 popen ("ls -la") 产生奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16389408/