以下命令在我的嵌入式Linux(Beaglebone Black)上正常运行:
echo bone_pwm_P9_21 > /sys/devices/bone_capemgr.?/slots
但不是在使用这个小型C ++程序时:
#include <stdlib.h>
#include <string>
int main {
system(std::string("echo bone_pwm_P9_21 > /sys/devices/bone_capemgr.?/slots").c_str());
return 0;
}
问题涉及'?'
问号,用作通配符。
当传递给std::string
的{{1}}中的问号被替换为普通字符时,system()
函数会对命令进行完美评估。
我尝试过的解决方案没有成功:
system()
替换为?
\?
替换为?
答案 0 :(得分:2)
除了您的代码无法编译之外,此操作失败,因为system(3)
运行sh
,通常是dash
或busybox
提供的最小外壳。
同时,您的互动式登录使用bash
,ksh
或其他一些更舒适的shell。
dash
和busybox sh
不会对重定向执行全局展开,而bash
和ksh
会执行。以下是您希望bash
提供的行为的演示:
$ touch file.txt
$ bash -c 'echo "bash contents" > *.txt'
$ cat file.txt
bash contents
与此同时,您遇到的问题包括: dash
:
$ dash -c 'echo "and now dash" > *.txt'
$ ls
*.txt file.txt
$ cat '*.txt' # Instead of expanding, the path was taken literally
and now dash
$ cat file.txt
bash contents
要解决此问题,您可以(按优先顺序)
execve
调用更好的shell。echo "stuff" | tee *.txt > /dev/null
system
调用更好的shell,例如bash -c "echo stuff > *.txt"
答案 1 :(得分:1)
注意:正如πάνταῥεῖ指出system()
命令调用shell,当使用正确的通配符时,它通常会进行扩展:*
。如果您希望控件单独进行每个system()
调用或者底层shell受限,那么这个答案更合适。
原始回答:
也许您可以使用 wordexp 来构建字符串,然后再进行system()
调用:
#include <string>
#include <vector>
#include <iostream>
#include <wordexp.h>
std::vector<std::string> expand_env(const std::string& var, int flags = 0)
{
std::vector<std::string> vars;
wordexp_t p;
if(!wordexp(var.c_str(), &p, flags))
{
if(p.we_wordc)
for(char** exp = p.we_wordv; *exp; ++exp)
vars.push_back(exp[0]);
wordfree(&p);
}
return vars;
}
int main()
{
for(auto&& s: expand_env("$HOME/*")) // <= Note the wildcard '*'
std::cout << s << '\n';
}
在您的具体情况下,您可以使用以下内容:
int main()
{
std::vector<std::string> devices = expand_env("/sys/devices/bone_capemgr.*/slots");
for(std::vector<std::string>::size_type i = 0; i < devices.size(); ++i)
system(("echo bone_pwm_P9_21 > " + devices[i]).c_str());
}