C - 使用Execvp执行Bash命令

时间:2013-01-03 14:39:41

标签: c bash execvp

我想编写一个程序Shellcode.c,它在输入中接受一个文本文件,其中包含由换行符分隔的bash命令,并执行文本文件中的每个命令:例如,文本文件将包含:

echo Hello World
mkdir goofy   
ls

我试过这个(只是开始练习一个exec函数):

#include <stdio.h>
#include <unistd.h>

void main() {
    char *name[3];

    name[0] = "echo";
    name[1] = "Hello World";
    name[2] = NULL;
    execvp("/bin/sh", name);
}

作为回报,我得到了

echo: Can't open Hello World

我坚持使用execvp函数,我哪里出错了?

3 个答案:

答案 0 :(得分:19)

你做错了。

第一个数组索引是程序的名称,如explained in the docs

  

execv(),execvp()和execvpe()函数提供了一个指向以null结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。按照惯例,第一个参数应指向与正在执行的文件关联的文件名。指针数组必须由NULL指针终止。

另外,bash不希望像这样的自由格式参数,你需要告诉它你将使用-c选项传递命令:

所以,你需要:

name[0] = "sh";
name[1] = "-c";
name[2] = "echo hello world";
name[3] = NULL;

答案 1 :(得分:9)

要在命令行上传递脚本bash,必须添加选项'-c'并将整个脚本作为单个字符串传递,即

#include <stdio.h>
#include <unistd.h>

void main() {
    char *name[] = {
        "/bin/bash",
        "-c",
        "echo 'Hello World'",
        NULL
    };
    execvp(name[0], name);
}

答案 2 :(得分:7)

此处存在许多问题: exec() 系列函数不执行多个程序 - 这些函数执行单个程序, 替换 新程序在内存中当前正在运行的进程。传递给execvp的以空字符串终止的字符串数组应该包含execvp执行的程序的命令行参数

如果要执行多个程序,则需要遍历每一行并逐个执行程序。但是你不能使用execvp,因为它会立即用shell执行的进程替换当前正在执行的进程(你的C程序),这意味着你的C程序的其余部分永远不会被执行。您需要了解如何使用 fork() execvp结合使用,以便执行子进程。您首先调用fork()创建子进程,然后从子进程调用execvp。在UNIX环境中Fork + Exec is a common strategy从父进程启动其他进程。