如何在system()中使用通配符expression式

下面的命令在我的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没有成功:

  • replace?\?
  • replace?*

注意:由于πάνταῥεῖ指出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。

同时,您的交互式登录使用bashksh或其他更舒适的shell。

dashbusybox sh不做重定向上的glob扩展,而bashksh做。 下面是你想要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 

要解决这个问题,你可以(按照优先顺序)

  1. 用C代码而不是shell脚本编写你的C程序
  2. execve调用更好的shell。
  3. 重写不写入glob,例如echo "stuff" | tee *.txt > /dev/null echo "stuff" | tee *.txt > /dev/null
  4. system调用一个更好的shell,比如bash -c "echo stuff > *.txt"