Perl包装器开发:实现外部程序的STDIN管道与STDOUT过滤
嘿,你已经用IPC::Run3迈出了Perl和Gekko交互的第一步!要实现STDIN管道传输和STDOUT实时过滤这两个功能,咱们可以对现有代码做一些针对性调整,下面给你具体的实现方案:
原代码与输出回顾
你的Perl代码
#!/usr/bin/perl -w use strict; use IPC::Run3 qw(run3); my $stdout; local $| = 1; run3 ['node','gekko',"-b","-c","BNB-XLM-Doktor_v1-5-144-config.js"], undef, $stdout;
程序输出
2018-03-18 13:50:10 (DEBUG): Available 142534
2018-03-18 13:50:10 (DEBUG): Optimal 144240
2018-03-18 13:50:10 (INFO): The database has 1707 candles missing, Figuring out which ones...
2018-03-18 13:50:11 (INFO): Gekko detected ...
功能1:STDOUT实时过滤
如果想在Gekko输出日志时就实时过滤(比如只保留INFO级别的日志,或者提取特定关键词内容),可以把run3的第三个参数(STDOUT目标)换成一个子程序引用,这样每一行输出都会触发这个子程序,在里面完成过滤逻辑:
#!/usr/bin/perl -w use strict; use IPC::Run3 qw(run3); local $| = 1; # 自定义STDOUT过滤子程序:只保留包含(INFO)的行 my $filter_stdout = sub { my $line = shift; # 过滤逻辑:这里只输出INFO级别的日志 print $line if $line =~ /\(INFO\)/; }; # 调用run3,将STDOUT导向过滤子程序 run3 [ 'node','gekko',"-b","-c","BNB-XLM-Doktor_v1-5-144-config.js" ], undef, $filter_stdout;
这段代码会实时打印Gekko输出的INFO级日志,DEBUG日志会被直接忽略。你可以根据需求修改$filter_stdout里的正则表达式或者逻辑,比如提取特定数值、过滤特定关键词等。
功能2:STDIN管道传输
如果需要给Gekko通过STDIN发送输入(比如交互式命令),可以把run3的第二个参数(STDIN源)设置为字符串、文件句柄或者子程序引用:
方式1:一次性发送输入字符串
如果是固定的输入内容,可以直接传字符串:
my $stdin_input = "some_command\nanother_command\n"; run3 [ 'node','gekko',"-b","-c","BNB-XLM-Doktor_v1-5-144-config.js" ], \$stdin_input, $filter_stdout;
方式2:动态生成输入(子程序)
如果需要根据Gekko的输出动态发送输入,可以用子程序作为STDIN源,每次Gekko请求输入时,这个子程序会被调用返回输入内容:
my $stdin_generator = sub { # 这里可以根据逻辑生成输入,比如读取用户输入或者计算结果 my $input = <STDIN>; # 示例:读取终端用户输入 return $input; }; run3 [ 'node','gekko',"-b","-c","BNB-XLM-Doktor_v1-5-144-config.js" ], $stdin_generator, $filter_stdout;
组合功能:同时实现STDIN传输与STDOUT过滤
把上面两个功能结合起来,就能同时完成双向交互和输出过滤了:
#!/usr/bin/perl -w use strict; use IPC::Run3 qw(run3); local $| = 1; # STDOUT过滤:只保留INFO日志 my $filter_stdout = sub { my $line = shift; print "过滤后输出:$line" if $line =~ /\(INFO\)/; }; # STDIN输入:动态读取终端输入 my $stdin_handler = sub { print "请输入Gekko命令:"; my $cmd = <STDIN>; return $cmd; }; # 启动交互 run3 [ 'node','gekko',"-b","-c","BNB-XLM-Doktor_v1-5-144-config.js" ], $stdin_handler, $filter_stdout;
这样你的Perl包装器就能和Gekko实时交互,同时只输出你关心的日志内容啦。
内容的提问来源于stack exchange,提问作者J. Doe

