如何添加一个空格字符来触发 var args c++ execlp()



我在Ubuntu上编写这个程序。如果我在外壳中键入此命令

组根系统箱

它输出

root : root
sys : sys
bin : bin

但是,我正在编写一个 c++ 程序,该程序使用 execlp 调用组

execlp("groups", "groups", args.c_str(), NULL);

其中 args = "根系统箱"。我只是得到一个:没有这样的用户错误,因为 groups' 显然只是将整个字符串视为 argv[0],这相当于运行

groups "root sys bin" 

如何为 execlp 创建正确的变量参数以在每个用户上运行组,一次一个?

一种选择是要求/bin/sh以正常方式处理输入。 当然,除了处理空格之外,这还将处理$#~*等字符,这些字符可能是您想要的,也可能不是您想要的。

execl("/bin/sh", "sh", "-c", ("groups " + args).c_str(), nullptr);

显然,如果数据是用户输入的并且可能包含令人讨厌的字符串,请不要使用这种方式,例如:

root ;rm *
否则,

除非您在编译时知道命令行参数的数量,否则execl类型函数将不起作用。 假设您的args字符串可能具有不同数量的参数,则需要execv类型函数。

std::string args = "root sys bin";
std::vector<std::string> arg_vec;
std::istringstream arg_iss(args);
std::copy(std::istream_iterator<std::string>(arg_iss),
          std::istream_iterator<std::string>(),
          std::back_inserter(arg_vec));
char groups_exec[] = "groups";
std::vector<char*> arg_ptr_vec{ groups_exec };
std::for_each(arg_vec.begin(), arg_vec.end(),
              [&](std::string& arg){ arg_ptr_vec.push_back(&arg[0]); } );
arg_ptr_vec.push_back(nullptr);
execvp("groups", arg_ptr_vec.data());

execlp 的 args 参数定义为"char *const argv[]",所以我认为你可以做类似的事情

const char *myArgs[3] = {"root, "sys", "bin"};

然后将 args.c_str() 替换为 myArgs。

我应该承认为 Ubuntu 编写软件的经验为零 - 如果我试图让 execlp 工作,这就是我接下来要尝试的。

编辑:这是错误的 - 我搞混了,正在看execv(),bobah和sleepy42似乎已经明白了。

最新更新