如何在C中运行shell命令

时间:2014-01-30 05:10:37

标签: c shell curl awk

在我的代码中,我需要了解一些IP地址的位置。为了获取此信息,我使用免费API向网站发送查询。因为C没有这种发送查询的能力,所以我决定在我的代码中运行一个shell脚本。网站返回的回复如下:

"IP address","US","United States","MI","Michigan","Dearborn","48121","42.3223","-83.1763","505","313"

我只需要这两个数字:"42.3223","-83.1763"(纬度和经度)
我的shell命令是:

curl freegeoip.net/csv/{IPaddress} | awk -F'","' '{print $8,$9}'

为了将shell代码运行到C中,我使用了system()函数,但是这个函数没有返回$8$9的值

int main ()
{
int i, ret = system("curl freegeoip.net/csv/{IPaddress} | awk -F'","' '{print $8,$9}'");
        printf("My val= %d\n",i);
        return 0;
}

我需要将这两个值返回到我的C代码中 我不想使用popen(),因为它每次打开和关闭一个文件,并且我的查询数量太高而且成本太高。

1 个答案:

答案 0 :(得分:0)

  

因为C没有这种发送查询的能力

确实如此。你认为curl和你的shell是什么写的?当然,在C语言中发出HTTP请求不是 easy ,但肯定是可能

  

我不想使用popen(),因为它每次都会打开和关闭一个文件,而且我的查询数量太高而且成本太高。

你的前提是错的,你的结论是错误的。 popen()不会打开文件,它会打开一个管道,该管道具有与之关联的文件描述符,并通过FILE*对象返回到您的代码。当你有一个管道时,一个进程写入管道的数据永远不会进入磁盘,它只是由操作系统存储在内存中。因此子进程将数据写入内存中的管道,父进程将数据读回,所有这些都没有碰到磁盘。

即使忽略这一点,这个程序的性能瓶颈也不会成为管道。网络比磁盘访问(或其他任何本地运行)慢一个数量级,因此瓶颈将是数据传输。在那之后,下一个瓶颈将是流程创建,这并不便宜,但它仍然比网络运营便宜。在这方面,你担心错误的事情,表现明智。

在这里使用popen(),这正是您所需要的。如果您需要运行大量查询,请考虑在一个命令行中运行它们以进行卷曲,以便它可以启用HTTP pipelining。如果没有这个,每个请求都必须在单独的TCP流上发送,这会增加整体延迟。如果您确实需要非常高的性能,请不要使用子进程 - 我建议将libcurl直接集成到您的程序中。