从execv运行mysql导入

时间:2012-02-11 19:54:56

标签: c execv

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登录,但第二个工作正常。无论如何,如果我添加到参数列表:

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

输出显示命令行args的mysql帮助,比如输入错误。 有人知道如何让它发挥作用吗?

3 个答案:

答案 0 :(得分:3)

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

  

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

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

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

答案 1 :(得分:2)

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

您无法使用execv重定向,因为这是一个shell功能,而execv不会运行shell。您可以执行/bin/sh,其参数指示它运行mysql,或者您可以使用dup2将标准输出更改为您想要的任何内容。

答案 2 :(得分:1)

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