如何在C++中转义发送到'system'命令的变量?

cwd*_*cwd 5 c++ linux escaping

这个问题讨论了使用system命令和传递变量.这是一个例子:

string cmd("curl -b cookie.txt -d test=");
cmd += line;
cmd += "  http://example.com";
system(cmd.c_str());
Run Code Online (Sandbox Code Playgroud)

其中一条评论提到,如果line通过并包含,foo & fire_nukes.exe & REM那么很可能发生一些不好的事情.

PHP有一个很好的函数escape_shell_args,可用于转义传递给程序的参数.C++有办法做到这一点吗?

Sta*_*ven 3

system()最好的办法就是根本不使用。使用fork()andexec()和朋友。这是一个例子:

#include <string>
#include <unistd.h>
#include <error.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <cstdlib>

int fork_curl(char *line)
{
    std::string linearg("line=");
    linearg += line;

    int pid = fork();
    if(pid != 0) {
        /* We're in the parent process, return the child's pid. */
        return pid;
    }
    /* Otherwise, we're in the child process, so let's exec curl. */

    execlp("curl", "-b", "cookie.txt", "-d", linearg.c_str());  
    /* exec is not supposed to return, so something
       must have gone wrong. */
    exit(100);
    /* Note: You should probably use an exit  status
       that doesn't collide with these used by curl, if possible. */
}

int main(int argc, char* argv[])
{
    int cpid = fork_curl("test");
    if(cpid == -1) {
        /* Failed to fork */
        error(1, errno, "Fork failed");
        return 1;
    }

    /* Optionally, wait for the child to exit and get
       the exit status. */
    int status;
    waitpid(cpid, &status, 0);
    if(! WIFEXITED(status)) {
        error(1, 0, "The child was killed or segfaulted or something\n");
    }

    status = WEXITSTATUS(status);
    /* Status now contains the exit status of the child process. */
}
Run Code Online (Sandbox Code Playgroud)