c - 如何在C中运行shell命令

标签 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(),因为它每次都会打开和关闭一个文件,而且我的查询数量太多,成本太高。

最佳答案

Because C does not have this ability to send queries

当然可以。您认为 curl 和您的 shell 是用什么编写的?当然,用 C 语言发出 HTTP 请求并不容易,但它肯定可能

I do not want to use popen(), because it opens and closes a file each time, and the number of my queries is too high which it would be too costly.

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

即使忽略这一点,该程序的性能瓶颈也不会是管道。网络比磁盘访问(或本地运行的其他任何东西)慢一个数量级,因此瓶颈将是数据传输。之后,下一个瓶颈将是进程创建,这并不便宜,但仍然比网络操作便宜得多。从性能角度来看,您在这里担心的是错误的事情。

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

关于c - 如何在C中运行shell命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21448289/

相关文章:

c - MacOS 从 Mavericks Lion 兼容的可执行文件编译

c++ - 为结构变量赋值

shell - 我可以在 unix 脚本中调用 ssh 中的函数吗

如果 php shell_exec 包含用于字符串替换的大括号,则它会默默失败

linux - 如何从 Linux 创建不存在的目录将文件发送到 Sharepoint

ruby-on-rails - 如何在 curl (bash) 脚本中使用 ruby​​ rails 变量

c - 给定密码验证码,我如何对密码进行反向工程

C文件同步

bash - 使用 shUnit2 在 bash 脚本中测试 "exit process command"

ssl - curl:无法使用自签名证书获取本地颁发者证书