C语言 C - 使用 Execvp 执行 Bash 命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14141007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:56:53  来源:igfitidea点击:

C - Executing Bash Commands with Execvp

cbashexecvp

提问by elmazzun

I want to write a program Shellcode.c that accepts in input a text file, which contains bash commands separeted by newline, and executes every commands in the text file: for example, the text file will contain:

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

echo Hello World
mkdir goofy   
ls

I tried this one (just to begin practicing with one of the exec functions):

我尝试了这个(只是为了开始练习 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);
}

I get, in return,

我得到,作为回报,

echo: Can't open Hello World

I'm stuck with the execvp function, where did I go wrong?

我被 execvp 函数卡住了,我哪里出错了?

回答by unwind

You're doing it wrong.

你这样做是错的。

The first array index is the name of the program, as explained in the docs:

第一个数组索引是程序的名称,如文档中所述

The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.

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

Also, bash doesn't expect free-form argument like that, you need to tell it you're going to pass commands using the -coption:

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

So, you need:

所以,你需要:

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

回答by datenwolf

To pass a script to bash on the command line you must add the option '-c' and pass the whole script as a single string, i.e.

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

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

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

回答by Charles Salvia

Many problems here: The exec()family of functions do not execute multiple programs - these functions execute a single program, and replacethe currently running process in memory with the new program. The null-pointer-terminated array of strings you pass to execvpis supposed to contain the command-line argumentsto the program executed by execvp.

这里有很多问题:exec()函数族不执行多个程序——这些函数执行单个程序,并新程序替换内存中当前运行的进程。串的空指针终止阵列传递给execvp应该包含命令行参数来通过执行的程序execvp

If you want to execute multiple programs, you'll need to loop over each line and execute the programs one by one. But you can't use execvpbecause that immediately replaces the currently executing process (your C program) with the process executed via the shell, meaning that the rest of your C program will never be executed. You need to learn how to use fork()combined with execvpso you can execute child processes. You first call fork()to create a child process, and then from the child process you call execvp. Fork + Exec is a common strategyin UNIX environments to launch other processes from a parent process.

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