下面的命令在我的embedded式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; }
问题涉及'?'
问号,用作通配符。 当传递给system()
的std::string
中的问号被一个普通字符replace时, system()
函数将评估完美命令。
我尝试过的解决scheme没有成功:
?
与\?
?
带*
注意:由于πάνταῥεῖ指出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()); }
除了你的代码不可编译之外,这个失败是因为system(3)
运行sh
,通常是由dash
或者busybox
提供的最小的shell。
同时,您的交互式登录使用bash
, ksh
或其他更舒适的shell。
dash
和busybox sh
不做重定向上的glob扩展,而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
echo "stuff" | tee *.txt > /dev/null
system
调用一个更好的shell,比如bash -c "echo stuff > *.txt"