我试图让我的程序使用exelp()
运行shell命令。用户基本上输入一个shell命令,该命令在新shell中由exelp()
存储然后执行。
让我们说用户输入“ ls -l / bin / ?? ”,然后由变量command[]
捕获。如何在shell环境中执行此文本字符串。
我最接近了解如何执行此操作的方法是execlp("/bin/sh", "-c", command, (char *)NULL);
,其中/bin/sh
启动迷你shell,-c
启用shell来获取字符串,最后一个参数只是先前捕获的字符串。我知道system()
是一个选项,但我想用execlp来做这个教育目的。
这里我错过了什么?提前谢谢。
答案 0 :(得分:0)
也许你在问如何在你的C程序中将shell单词扩展为参数子序列。见glob(7)
然后考虑glob(3)和wordexp(3)
你应该意识到当你输入ls -l /bin/??
时,外壳有责任扩展??
; /bin/ls
程序execve(2) - 使用扩展 的结果
或者,您可以将其留给由system(3)或popen(3)函数启动的/bin/sh -c
shell。如果您将一些用户输入传递给这些函数,请注意code injection并适当引用任何用户输入。想象一下,你运行一个由ls -l
和一些用户输入组成的字符串;如果恶意用户将a; rm -rf $HOME
作为文件名,那么如果你不引用它会很抱歉(因为没有预防措施,你的程序将构建ls -l a; rm -rf $HOME
命令字符串,然后将该字符串传递给{{ 1}}或system
然后灾难发生。)
答案 1 :(得分:-1)
您将const char**
而不是const char *
作为tird参数
尝试execlp("/bin/sh", "-c", "ls", "-l", "/bin/", 0)
或者使用“-c”作为第一个参数创建另一个char **,然后使用execv
我猜它正在编译,因为两个参数都是指针,但它们的类型错误
修改强>
当你像调用execlp一样。
正如你所说的命令是const char[]
,但在定义中你只需要const char*
就好像你像这样调用函数
execlp(const char*, const char*, const char **, char*) //wrong obviously
所以你有两个解决方案。 第一个使用bin / sh -c来连接所有参数并将其传递给execlp
int main(int argc, char **av)
{
char **args;
int i;
char *cmd;
size_t size;
args = malloc(sizeof(char*) * (4));
args[0] = "sh";
args[1] = "-c";
i = 1;
size = 0;
cmd = malloc(1);
*cmd = '\0';
while (i < argc)
{
cmd = realloc(cmd, strlen(cmd) + 1 + strlen(av[i]));
strcat(&(cmd[size]), av[i]);
size += strlen(cmd);
strcat(&(cmd[size]), " ");
size++;
i++;
}
args[2] = cmd;
execvp("/bin/sh", args);
}
但它不是很干净
最好的方法(对我而言更合乎逻辑)我认为在你的case / bin / ls中找到二进制文件的地址然后使用execvp
传递它
类似的东西:
char *get_binary_addr(const char* fct)
{
return "/bin/ls"; //ofc you will parse your /bin to find binary addr
}
int main(int argc, char **av)
{
char **args;
args = malloc(sizeof(char*) * argc);
memcpy(&(args[0]), &(av[1]), argc * sizeof(char*));
execvp(get_binary_addr(av[0]), args);
}