【问题标题】:Syntax error calling Python from C with fork-execv使用 fork-execv 从 C 调用 Python 的语法错误
【发布时间】:2021-12-17 02:38:44
【问题描述】:

我想使用 fork 和 execv 从 C 程序调用 Python 脚本作为子进程。我已经测试了它调用 bin/ls 并且它可以工作:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    int status;
    char *args[2];

    args[0] = "/bin/ls"; 
    args[1] = NULL; 

    if ( fork() == 0 ){
        printf("I am the child\n");
        execv( args[0], args ); }
    else {
        printf("I am the parent\n");
        wait( &status ); }

    return 0;
}

所以我更改了 C 代码以在这个 Python 文件中调用 Create_Buffer() 函数:

#!/usr/bin/python3

from nltk.corpus import gutenberg

def Create_Buffer():

    out_buf = []
    pointer = id(out_buf)

    value_in = 21

    print("I was here")
    print(value_in)

    return pointer

def NLTK_Python_Libs(n):

    if n == 0:
        n = n + 1
        return id(n)

Python 脚本有两个功能;我想调用 Create_Buffer(),所以我把我的 C 文件改成:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    int status;
    char * paramsList[] = { "/bin/bash", "-c", "/usr/bin/python",   "/opt/P01_SH/NLTK_Gutenberg/NLTK_Python_Libs.Create_Buffer()", (char *)NULL };

    if ( fork() == 0 ){
        printf("I am the child\n");
        execv("/usr/bin/python",paramsList); }
    else {
        printf("I am the parent\n");
        wait( &status ); }

    return 0;
}

但是运行时出现语法错误:

我是家长

我是孩子

文件“字符串”,第 1 行

/usr/bin/python

SyntaxError: 无效语法

接下来我稍微改变了一下,但我得到了一个不同的错误(如下所述):

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    int status;
    char *args[5];
    args[0] = "/bin/bash";
    args[1] = "-c";
    args[2] = "/usr/bin/python";
    args[3] =   "/opt/P01_SH/NLTK_Gutenberg/NLTK_Python_Libs.Create_Buffer()"; 
    args[4] = NULL;

    if ( fork() == 0 ){
        printf("I am the child\n");
        execv(args[0], args); }
    else {
        printf("I am the parent\n");
        wait( &status ); }

    return 0;
}

而这一次它调用了 Python 命令行而不是调用程序:

我是家长

我是孩子

Python 3.8.0(默认,2021 年 2 月 25 日,22:10:10)

Linux 上的[GCC 8.4.0]

输入“帮助”、“版权”、“信用”或“许可”以了解更多信息。

[Python 命令提示符]

这些错误似乎与 Python 文件顶部的 shebang 行有关,但无论我使用 #!/usr/bin/python、#!/usr/bin/python3 还是 #!/usr,都会遇到相同的错误/bin/env python3,或者把 shebang 行去掉。

所以我的问题是:当我想在 Python .py 文件中调用程序时,如何指定 fork-execv 的参数?我愿意使用任何其他 exec* 系列,除了我想使用绝对路径,如上所述,而不是添加到 Python PATH,所以我不想使用带有“p”的 exec 调用名字。

我进行了广泛的研究,但我没有找到任何示例显示在 Python 文件中调用特定程序并将参数传递给程序的语法。我见过调用 Python 文件的示例,但没有在文件中指定程序,也没有传递参数,但我需要按名称调用函数。

编译C程序:

gcc -fPIC -ggdb -o NLTK_Python.exe NLTK_Python.c -Wall -Wextra

我在 Ubuntu 18.04 上使用 Python 3.8。

感谢您对此的任何帮助。

【问题讨论】:

  • /python -c 期望下一个参数是要执行的 Python 语句。 /usr/bin/python 不是有效的 Python 语句。
  • bin/bash 对于第一行是否正确,在 -c 之后是要调用的 Python 程序吗?我刚刚更改了文件,以便 Python 程序(带路径)是第一个参数——没有错误,但它没有执行 Python 程序。

标签: python c python-3.x linux exec


【解决方案1】:

我想这就是你想要的:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    int status;
    char * paramsList[] = {
        "/usr/bin/python",
            "-m",
            "NLTK_Python_Libs",
            "-c",
            "NLTK_Python_Libs.Create_Buffer()",
            (char *)NULL };

    if ( fork() == 0 ){
        printf("I am the child\n");
        execv(paramsList[0],paramsList); }
    else {
        printf("I am the parent\n");
        wait( &status ); }

    return 0;
}

-m 选项告诉它加载NLTK_Python_Libs 模块。然后-c 告诉它从该模块执行一个函数。您不能将脚本路径名与函数名结合起来以按照您的方式执行。

根本不需要使用/bin/bash。直接执行python即可。

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 2016-12-17
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    相关资源
    最近更新 更多