使用 linux system() 函数 C++ beagle bone 问题
Using linux system() function C++ beagle bone issue
我四处搜索但找不到问题的答案。
我正在为 beagle bone black 交叉编译 C++ 应用程序并希望使用 linux system() 函数,如下所示:
系统("echo DM-GPIO-Test > $SLOTS");
就是添加一个device overlay来控制GPIO引脚。 echo 命令 "echo DM-GPIO-Test > $SLOTS" 在终端上从任何地方直接在 beagle bone 上执行时工作正常。 SLOTS是我定义的环境变量,DM-GPIO-Test-00A0.dtb0在/lib/firmware
但是,我在执行 C++ 应用程序时遇到以下错误:
"sh: 1: cannot create : Directory nonexistent"
是不是像我这样调用系统函数不正确?
提前致谢
No, it doesn't display anything doing system("echo $SLOTS")
在这种情况下,环境变量 SLOTS
只是您应用程序使用的环境中的 unset/empty。根据您的用例,您需要在启动二进制文件之前设置它,或者使用 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
ing'不符合要求。
请注意,最好将包含字符串的 shell 变量括在双引号中,以防它们包含空格,并将标识符括在大括号中,以避免歧义:
system("echo DM-GPIO-Test > \"${SLOTS}\"");
正如 Basile 在单独的答案中指出的那样,避免调用 shell 并处理完全用 C 编写文件的逻辑在处理错误和特殊情况方面甚至会更强大,但是还会产生更多代码(可能包含其自身的错误...)。
system("echo DM-GPIO-Test > $SLOTS");
这闻起来很难闻,应该避免。
您可能想要的是在您的 SLOTS
环境变量给定的文件中写入一个字符串(参见 environ(7)). For that particular use, you don't need to fork any /bin/sh
process (which is what system(3) does). You could simply fetch that environment variable using 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 or systemd)启动的 - 可能与您的交互式环境不同(并且更小)。
也许你的 slotspath
不应该来自你的环境,而是来自 /etc/
下的一些配置文件(你的程序应该解析),或者一些程序参数。
所以我建议定义一些配置文件的格式并解析它,然后从中得到你的slotspath
。
我四处搜索但找不到问题的答案。
我正在为 beagle bone black 交叉编译 C++ 应用程序并希望使用 linux system() 函数,如下所示:
系统("echo DM-GPIO-Test > $SLOTS");
就是添加一个device overlay来控制GPIO引脚。 echo 命令 "echo DM-GPIO-Test > $SLOTS" 在终端上从任何地方直接在 beagle bone 上执行时工作正常。 SLOTS是我定义的环境变量,DM-GPIO-Test-00A0.dtb0在/lib/firmware
但是,我在执行 C++ 应用程序时遇到以下错误:
"sh: 1: cannot create : Directory nonexistent"
是不是像我这样调用系统函数不正确?
提前致谢
No, it doesn't display anything doing system("echo $SLOTS")
在这种情况下,环境变量 SLOTS
只是您应用程序使用的环境中的 unset/empty。根据您的用例,您需要在启动二进制文件之前设置它,或者使用 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
ing'不符合要求。
请注意,最好将包含字符串的 shell 变量括在双引号中,以防它们包含空格,并将标识符括在大括号中,以避免歧义:
system("echo DM-GPIO-Test > \"${SLOTS}\"");
正如 Basile 在单独的答案中指出的那样,避免调用 shell 并处理完全用 C 编写文件的逻辑在处理错误和特殊情况方面甚至会更强大,但是还会产生更多代码(可能包含其自身的错误...)。
system("echo DM-GPIO-Test > $SLOTS");
这闻起来很难闻,应该避免。
您可能想要的是在您的 SLOTS
环境变量给定的文件中写入一个字符串(参见 environ(7)). For that particular use, you don't need to fork any /bin/sh
process (which is what system(3) does). You could simply fetch that environment variable using 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 or systemd)启动的 - 可能与您的交互式环境不同(并且更小)。
也许你的 slotspath
不应该来自你的环境,而是来自 /etc/
下的一些配置文件(你的程序应该解析),或者一些程序参数。
所以我建议定义一些配置文件的格式并解析它,然后从中得到你的slotspath
。