【问题标题】:Using linux system() function C++ beagle bone issue [closed]使用 linux system() 函数 C++ beagle bone 问题 [关闭]
【发布时间】:2018-01-14 20:24:43
【问题描述】:

我已经四处寻找,但找不到我的问题的答案。

我正在为 beagle bone black 交叉编译一个 C++ 应用程序,并希望按如下方式使用 linux system() 函数:

system("echo DM-GPIO-Test > $SLOTS");

它是添加一个设备覆盖来控制GPIO引脚。回声命令“echo DM-GPIO-Test > $SLOTS”在任何地方直接在小猎犬骨头上的终端上执行时都可以正常工作。 SLOTS 是我定义的环境变量,DM-GPIO-Test-00A0.dtb0 在 /lib/firmware

我在执行 c++ 应用程序时收到以下错误:

“sh: 1: 无法创建:目录不存在”

像我这样调用系统函数是不是不对?

提前致谢

【问题讨论】:

  • system("echo $SLOTS"); 是否显示任何内容?作为旁注,您的示例中没有任何特定于 C++ 的内容。
  • 您是否使用您在 shell 中使用的同一用户运行它?
  • 不,它不显示任何执行 system("echo $SLOTS");.但是,错误消失了。我正在使用 sudo 运行应用程序。我也尝试将 sudo 放入系统函数的字符串中,但没有。 @ DYZ,是的,你是对的,实际上没有特定的 C++。这是C
  • 在这种情况下不要使用system。您应该使用fopen+fprintf+fclose 并使用getenv("SLOTS") 获取$SLOTS 路径,检查并将其传递给fopen
  • 你的问题被否决了,因为它缺少一些minimal reproducible example

标签: c linux debian beagleboneblack


【解决方案1】:

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。

【讨论】:

  • 谢谢!很多我不知道的东西。知道为什么像我这样的问题会得到 -4 的反对票吗?
【解决方案2】:

不,它不显示任何执行 system("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() 获取它,如果它不符合要求,则使用asserting。

请注意,最好将包含字符串的 shell 变量括在双引号中,以防它们包含空格,并将标识符括在大括号中,以避免歧义:

system("echo DM-GPIO-Test > \"${SLOTS}\"");

正如 Basile 在单独的答案中指出的那样,避免调用 shell 并处理完全用 C 编写文件的逻辑在处理错误和特殊情况方面甚至会更强大,但也会导致更多代码 (其中可能包含自己的错误...)。

【讨论】:

  • 好吧,看起来是这样。为什么会发生这种情况你知道吗?我的应用程序是从 /root 执行的。如果我可以从终端直接在根目录中回显 $SLOTS,则表明它已设置,但不是来自应用程序。谢谢
  • 缺少一个水晶球,我不知道为什么没有。您的工作是找出应该设置的位置,以及为什么在您的应用程序启动的环境中没有这样做。
  • 嗯,好的。我在 ~/.profile 中设置了环境变量。我想他们只会在 shell 会话中被注意到?我应该将它们设置为我想要的其他地方吗?抱歉,我不是 Linux 专家
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 2019-01-05
  • 1970-01-01
  • 2015-09-01
相关资源
最近更新 更多