我在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似乎已经明白了。