0
pid_t childPid = fork ();
if (childPid == (pid_t) 0)//zero success
{
    const char *path = "/usr/local/mysql/bin/mysql";
    //doesn't work
    //char * const parmList[] = {"--user=root", "test_db", NULL};
    //does work
    char * const parmList[] = {"", "--user=root", "test_db", NULL};
    execv(path, parmList);
    printf("ERROR:\tFork failed.\n");   
}
else if (childPid < (pid_t) 0)// -1 failure
{
    /* The fork failed. */
    printf("ERROR:\tFork failed.\n");   
    return EXIT_FAILURE;
}
else
{
    while (true) {
        //stay alive
        sleep(1);
    }
}
printf("done");
exit(0);

我在使用 execv 导入 sql 转储时遇到问题。您可以看到我无法使用第一个 paramList 登录,但第二个 paramList 工作得很好。无论如何,如果我添加到参数列表:

char * const parmList[] = {"", "--user=root", "test_db", "<", "/Users/joelsaltzman/Desktop/dump.sql", NULL};

输出显示命令行参数的 mysql 帮助,就像我输入错误一样。有人知道如何让它工作吗?

4

3 回答 3

3

第一个paramList是不正确的,因为第一个元素应该是您要执行的程序的文件名:

参数 argv 是指向以空字符结尾的字符串的字符指针数组。应用程序应确保该数组的最后一个成员是空指针。这些字符串应构成可用于新过程映像的参数列表。argv[0] 中的值应该指向一个文件名,该文件名与正在由 exec 函数之一启动的进程相关联。

输入重定向<不起作用,因为这不是内核(您调用使用execv)的功能,而是通常的 Unix shell 的功能。库system调用是您正在寻找的。(它也只是使用来自exec-family 的调用,但使用您的命令调用 shell,然后它将支持<.)

system(3)如果您要向其传递可能受恶意用户影响的字符串,请务必阅读手册页并考虑输入验证。

于 2012-02-11T20:10:26.590 回答
2

第二个效果更好,因为第一个参数应该是命令名。因此,MySQL 从第二个参数开始读取。您应该使用命令名称(路径),而不是空字符串,但这通常无关紧要。

您不能将重定向与 一起使用execv,因为这是一个 shell 功能,并且execv不运行 shell。您可以执行/bin/sh,使用告诉它运行的参数mysql,或者您可以使用dup2将标准输入更改为您想要的任何内容。

于 2012-02-11T20:10:56.430 回答
1

改为使用popen()启动mysql,然后自己将sql文件的内容写入进程。

于 2012-02-11T20:14:32.217 回答