MySQL 中的用户定义函数(C/C++ 扩展插件)。无法执行系统命令

问题描述 投票:0回答:1

我正在尝试为MySQL创建用户定义的函数(根据本文档https://dev.mysql.com/doc/extending-mysql/8.0/en/adding-loadable-function.html)并创建新命令my_udf 将通过系统调用运行 Python 脚本,但它不起作用。

#include <mysql/mysql.h>
#include <string>
#include <iostream>
#include <cstring>

extern "C" bool my_udf_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
{
    if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
        strcpy(message, "Expected a single string argument");
        return 1;
    }

    initid->const_item = 1;     // This UDF is deterministic
    initid->maybe_null = 1;     // This UDF can return NULL
    initid->max_length = 0;     // The result can be of any length

    return 0;
}

extern "C" char* my_udf(UDF_INIT* initid, UDF_ARGS* args, char* result,
                        unsigned long* length, char* is_null, char* error)
{
    // Print the input string
    

    // Run the Python script and pass the input string as a command-line parameter
    char param[] = "params to script";
    char cmd[100];
    sprintf(cmd, "python3 checker.py %s", param);
    system(cmd);

    return 0;
}

我的Python脚本一切正常,我检查了两次。

我认为调用系统(cmd)有问题。

c++ mysql user-defined-functions
1个回答
0
投票

由于 MySQL 的安全限制和权限问题,使用 system() 从 MySQL UDF 运行 Python 脚本可能会出现问题。相反,使用 popen() 执行脚本并捕获其输出。这是代码的重构版本:

#include <mysql/mysql.h>
#include <string>
#include <cstdio>

extern "C" bool my_udf_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
    if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
        strcpy(message, "Expected a single string argument");
        return 1;
    }
    initid->const_item = 1; 
    initid->maybe_null = 1; 
    initid->max_length = 0; 
    return 0;
}

extern "C" char* my_udf(UDF_INIT* initid, UDF_ARGS* args, char* result,
                        unsigned long* length, char* is_null, char* error) {
    char cmd[200];
    sprintf(cmd, "python3 checker.py %s", args->args[0]);

    FILE* pipe = popen(cmd, "r");
    if (!pipe) {
        strcpy(error, "Failed to run command");
        return NULL;
    }

    char buffer[128];
    std::string output = "";
    while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
        output += buffer;
    }

    pclose(pipe);
    *length = output.size();
    strcpy(result, output.c_str());
    return result;
}

使用 popen() 运行 Python 脚本。 确保MySQL用户具有执行命令的正确权限。 如果您还有其他问题,请检查 MySQL 日志中是否有与权限相关的错误。

© www.soinside.com 2019 - 2024. All rights reserved.