[英]Running a simple Python script from Ada program
Does someone would have a simplest as possible way to run a Python script from the Ada project?有人会以最简单的方式从 Ada 项目运行 Python 脚本吗?
The Python script in this case only has a print in a loop, with a sleep, so each iteration it should print the arguments.在这种情况下,Python 脚本只有一个循环打印,带有睡眠,所以每次迭代它都应该打印 arguments。
The Python script I'm using is我正在使用的 Python 脚本是
import sys
import time
for index in range(10):
print(sys.argv)
time.sleep(1)
On approach I am trying is running this one as a batch script, so using我正在尝试的方法是将这个作为批处理脚本运行,所以使用
with Text_IO;
with Interfaces.C; use Interfaces.C;
procedure systest2 is
function Sys (Arg : Char_Array) return Integer;
pragma Import(C, Sys, "system");
Ret_Val : Integer;
begin
Ret_Val := Sys(To_C("python testpy.py arg1 arg2"));
end systest2;
The problem is that the execution blocks the script, meaning that the Python printouts are only printed at the end of the execution, at once.问题是执行阻塞了脚本,这意味着 Python 打印输出仅在执行结束时立即打印。
I know that there is a solution (to run Python from Ada) based on GNATCOLL, but I couldn't find any example to run it.我知道有一个基于 GNATCOLL 的解决方案(从 Ada 运行 Python),但我找不到任何示例来运行它。
Update更新
Just to clarify.只是为了澄清。 So I will try to simplify a bit the question.
所以我会尽量简化这个问题。 I want to do the equivalent of this in C:
我想在 C 中做同样的事情:
#include <stdio.h>
#include <stdlib.h>
int main(){
system("python testpy.py ddddd");
return 0;
}
In this case it does not block the testpy.py printouts.在这种情况下,它不会阻止 testpy.py 打印输出。
But I am doing this但我正在这样做
with Interfaces.C; use Interfaces.C;
procedure systest2 is
function Sys (Arg : Char_Array) return Integer;
pragma Import(C, Sys, "system");
Ret_Val : Integer;
begin
Ret_Val := Sys(To_C("python testpy.py arg1 arg2"));
end systest2;
which blocks the testpy.py script until its end.这会阻止 testpy.py 脚本直到它结束。 This should not happen.
这不应该发生。
So, please, how could I fix this?那么,请问,我该如何解决这个问题?
Below is an example that might help (tested with GNAT CE 2019 on Linux).下面是一个可能有帮助的示例(在 Linux 上使用 GNAT CE 2019 进行了测试)。 It's based on the
GNAT.Expect
package and the example that was given in one of AdaCore's Gem articles .它基于
GNAT.Expect
package 和AdaCore 的 Gem 文章之一中给出的示例。 In the example, a new process is spawned and pipes are automatically connected.在示例中,生成了一个新进程并自动连接了管道。
Two remarks:两个备注:
It's important to run the python interpreter with I/O buffering disabled (using the -u
option).在禁用 I/O 缓冲(使用
-u
选项)的情况下运行 python 解释器很重要。 If this is undesirable, then you can, alternatively, also use the flush option on the print
statement in Python 3 ie print(..., flush=True)
.如果这是不可取的,那么您也可以在 Python 3 中的
print
语句上使用 flush 选项,即print(..., flush=True)
。 When you don't disable the I/O buffering or flush the I/O buffer behind print
, you will run into timeouts.如果您不禁用 I/O 缓冲或在
print
后面刷新 I/O 缓冲区,您将遇到超时。
The Python script is, for now, just killed via the Close
statement (it just sends the SIGKILL
signal on Linux). Python 脚本目前只是通过
Close
语句终止(它只是在 Linux 上发送SIGKILL
信号)。
main.adb主文件
with Ada.Text_IO; use Ada.Text_IO;
with GNAT.Expect; use GNAT.Expect;
with GNAT.OS_Lib; use GNAT.OS_Lib;
procedure Main is
Command : constant String := "python -u test.py 123";
Pd : Process_Descriptor;
Args : Argument_List_Access;
Result : Expect_Match;
begin
Args := Argument_String_To_List (Command);
Non_Blocking_Spawn
(Pd,
Command => Args (Args'First).all,
Args => Args (Args'First + 1 .. Args'Last),
Buffer_Size => 0);
for I in 1 .. 10 loop
Expect (Pd, Result, Regexp => "\d+", Timeout => 2_000);
case Result is
when Expect_Timeout =>
Put_Line ("Expect timed out.");
when 1 =>
Put_Line ("Received: " & Expect_Out_Match (Pd));
when others =>
raise Program_Error;
end case;
Put_Line ("Doing other stuff...");
end loop;
Close (Pd);
Free (Args);
exception
when Process_Died =>
Put_Line ("Process died.");
Close (Pd);
Free (Args);
end Main;
test.py测试.py
import sys
import time
while True:
print(sys.argv[1])
time.sleep(1)
output output
$ ./main
Received: 123
Doing other stuff...
Received: 123
Doing other stuff...
Received: 123
(repeated another 7 times).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.