我在C中编程为嵌入式设备创建一些API。这个嵌入式设备运行Linux的变体。我对C不是很熟悉 - 我对shell脚本/ bash更熟悉。
考虑到这一点,当涉及检查目录是否存在或获取磁盘使用时,我发现只需调用system
或popen
并执行我的命令就更容易了,然后解析输出。作为开发人员,我的速度更快。
进行这些system
和popen
调用是否有缺点,而不是在C中找出如何处理这些内容然后再使用C&C的函数?
答案 0 :(得分:4)
即使它可以在Linux上运行,也不能依赖于您打算使用的所有命令的可用性,因此缺点是直接的:您不能依赖一个给定的工具可用。
要考虑的另一件事是从c解析shell命令的输出非常困难。
最后,您无法让程序随机调用系统实用程序或shell脚本,因为它不安全。
答案 1 :(得分:4)
缺点:
优点:
system("ls -1");
总结 -
这取决于你需要做什么,但一般情况下有更多的负面因素而不是正数。
答案 2 :(得分:2)
在一天结束时,在Linux系统上,几乎所有东西都在某个时候调用C函数。
要触及评论中的一些论点以及我自己的想法:
编辑以解决Pimgd的评论:请注意,竞争条件是一个痛苦的问题,其中很多不一定是您的特定用例的问题,但至少在衡量pro / con时是值得考虑的。无论如何,我正在考虑的特定竞争条件实例包括(并且可能还有其他类):
多进程竞争条件。我能想到的最简单的例子是,如果程序的两个实例想要设置配置文件并且同时运行,会发生什么。某些操作系统调用对原子性有一定程度的保证,但是如果调用一系列shell命令来写入文件,则会丢失很多。 (请注意,即使您从单片C应用程序而不是一系列shell命令执行此操作,您仍需要做一些额外的操作来防止实例1覆盖实例2的更改,但您至少不会遇到最终混合变化的情况。例如:
FILE * fp = fopen(“config.txt”,“wt”);
fprintf(fp,“Config value 1:%s”,config [0]);
fprintf(fp,“Config value 2:%s”,config [1]);
fflush(FP);
FCLOSE(FP);
VS
system("echo Config value 1: `df | awk '{print $1}'` > config.txt");
system("echo Config value 2: `ps | grep foo | awk '{print $2}'` >> config.txt");
如果程序的两个实例在接近确切的时间运行,那么最终可以使用例如在后一种情况下,配置文件中有2个Config值为2的实例。
答案 3 :(得分:2)
也许这是一种有效的方法,让你更熟悉shell脚本,就像这样:
使用shell脚本作为基础,执行所有高级计算。该脚本可以使用一个(或多个)命令来寻址API;只提供这些命令,编写小型C程序。
例如:
#!/bin/bash
valueA=$(APIhelper -q valueA)
valueB=$(APIhelper -q valueB)
process() { … }
result=$(process "$valueA" "$valueB")
APIhelper -s result "$result"
如果您了解shell脚本,则应该清楚这一部分。
现在您只需要编写二进制文件APIhelper
(请根据您的上下文选择更合适的名称; - )。
这可以是这样的C程序:
int main(int argc, char *argv[]) {
if (argc > 1) {
if (strstr(argv[1], "-q") == 0) {
if (argc > 2) {
char *variableName = argv[2];
someType result = makeYourApiCall(variableName);
printf("%O\n", result); # use a fitting format instead of %O!
} else {
fprintf(stderr, "-q without variable name\n");
exit(1);
}
else if (strstr(argv[1], "-s") == 0) {
…
} else {
fprintf(stderr, "option not understood: %s\n", argv[1]);
exit(1);
}
} else {
fprintf(stderr, "missing option\n");
exit(1);
}
return 0;
}
这种方式只能在C程序中完成API的最基本处理,您可以坚持使用最佳代码:脚本。此外,通过这种方式,您可以轻松地调试API,因为可以通过交互方式从命令行调用此工具APIhelper
。