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 を使用してログインできなかったことがわかりますが、2 番目の paramList は問題なく機能しました。とにかく、param リストに追加すると:

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

出力には、何か間違ったことを入力したようなコマンド ライン引数の mysql ヘルプが表示されます。これを機能させる方法を知っている人はいますか?

4

3 に答える 3

3

最初paramListの要素は実行するプログラムのファイル名でなければならないため、最初の要素は正しくありません。

引数 argv は、ヌル終了文字列への文字ポインタの配列です。アプリケーションは、この配列の最後のメンバーがヌル ポインターであることを確認する必要があります。これらの文字列は、新しいプロセス イメージで使用できる引数リストを構成します。argv[0] の値は、exec 関数の 1 つによって開始されるプロセスに関連付けられたファイル名を指す必要があります。

での入力リダイレクトは<機能しません。これはカーネル ( を使用して呼び出すexecv) の機能ではなく、通常の Unix シェルの機能であるためです。ライブラリ呼び出しは、systemあなたが探しているものです。(これも - ファミリーからの呼び出しを使用しexecますが、コマンドでシェルを呼び出します。これにより、 がサポートされ<ます。)

system(3)悪意のあるユーザーの影響を受ける可能性のある文字列を渡す場合は、必ずマンページを読み、入力の検証について考えてください。

于 2012-02-11T20:10:26.590 に答える
2

最初のパラメーターはコマンド名にする必要があるため、2 番目のパラメーターの方がうまく機能します。したがって、MySQL は 2 番目のパラメーターから読み取りを開始します。空の文字列ではなく、コマンド名 (パス) を使用する必要がありますが、通常は問題ありません。

execvこれはシェル機能であり、execvシェルを実行しないため、 でリダイレクトを使用することはできません。run を実行/bin/shするように指示するパラメーターを使用して を実行するか、 stdin を必要なものに変更するためにmysql使用できます。dup2

于 2012-02-11T20:10:56.430 に答える
1

代わりに使用popen()して mysql を起動し、sql ファイルの内容を自分でプロセスに書き込みます。

于 2012-02-11T20:14:32.217 に答える