我已经四处寻找但无法找到问题的答案。
我正在为beagle bone black交叉编译一个C ++应用程序,并希望使用linux system()函数,如下所示:
系统(" echo DM-GPIO-Test> $ SLOTS");
添加器件覆盖以控制GPIO引脚。 echo命令" echo DM-GPIO-Test> $ SLOTS"从任何地方直接在beagle bone上的终端上执行时工作正常。 SLOTS是我定义的环境变量,DM-GPIO-Test-00A0.dtb0位于/ lib / firmware
但是在执行c ++应用程序时遇到以下错误:
" sh:1:无法创建:目录不存在"
像我一样调用系统函数是不正确的?
提前致谢
答案 0 :(得分:2)
不,它没有显示任何正在做系统的事情(" echo $ SLOTS")
在这种情况下,环境变量SLOTS
在应用程序使用的环境中简单地取消设置/清空。根据您的使用情况,您需要在启动二进制文件之前设置它,或者使用setenv()
,或者直接将其替换为传递给system()
的字符串。如果您希望在任何用户的配置文件设置中设置变量,则需要在调用时了解shell的不同行为(例如bash),并将其放在正确的文件中,或创建一个设置它的包装器脚本。
$ cat .profile
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
[...]
一个好主意也是在system()
来电之前检查应用中的有效值,使用getenv()
获取有效值,assert
如果它没有&#39}符合要求。
请注意,最好将包含字符串的shell变量括在双引号中,以防它们包含空格,并将标识符括在大括号中,以避免含糊不清:
system("echo DM-GPIO-Test > \"${SLOTS}\"");
正如Basile在单独的回答中指出的那样,避免调用shell并处理在C中完全编写文件的逻辑在处理错误和特殊情况时甚至会更强大,但也会产生更多的代码(这可能包含自己的错误......)。
答案 1 :(得分:2)
system("echo DM-GPIO-Test > $SLOTS");
这闻起来很糟糕,应该避免。
您可能想要的是在SLOTS
环境变量给出的文件中写一个字符串(参见environ(7))。对于该特定用途,您不需要分叉任何/bin/sh
进程(这是system(3)所做的)。您可以使用getenv(3)简单地获取该环境变量。
所以你可以试试:
const char*slotspath = getenv("SLOTS");
if (!slotspath) {
fprintf(stderr, "no SLOTS\n");
exit(EXIT_FAILURE);
}
FILE* fslots = fopen(slotspath, "w");
if (!fslots) { perror(slotspath); exit(EXIT_FAILURE); };
fputs("DM-GPIO-Test\n", fslots);
fclose(fslots), fslots = NULL;
请注意,您的程序环境 - 通过其他实用程序(或来自init或systemd)启动 - 可能与您的交互式环境不同(并且更小)。
也许您的slotspath
不应该来自您的环境,而是来自/etc/
下的某个配置文件(您的程序应该解析)或某些程序参数。
所以我建议定义一些配置文件的格式并解析它,并从中获取slotspath
。