如何通过 Perl 以编程方式控制交互式 Unix 应用程序?
我继承了一个已有 20 年历史的交互式命令行 unix 应用程序,该应用程序不再受到其供应商的支持。我们需要自动化此应用程序中的一些任务。
其中最麻烦的是创建数千条参数略有不同的新记录(例如不同的标识符、不同的名称)。必须按顺序创建记录,一次创建一个,这需要花费数月(因此也需要花费大量资金)手动完成。在大多数情况下,创建记录具有非常可预测的模式,即键入命令、读取响应、键入进一步的命令等。但是,某些记录创建操作将导致错误条件(“具有此标识符的记录已存在”),这需要一组不同的命令可以正常退出。
我可以看到几种不同的方法来做到这一点:
命名管道。编写一个 Perl 脚本,运行目标应用程序并将 STDIN 和 STDOUT 设置为命名管道,然后向目标应用程序发送命令序列以创建具有所需参数的记录,然后指示目标应用程序退出并关闭。然后,我们使用不同的参数根据需要多次运行该脚本。
申请。寻找另一个可用于编写交互式程序脚本的 Unix 工具。我唯一能找到的是 expect,但这似乎无法维护;和聊天,我记得很久以前,它似乎或多或少做了我想要的,但似乎只用于控制调制解调器。
另一个潜在的复杂性:我认为目标应用程序是为 VT100 终端编写的,它使用某种转义序列来执行诸如提供突出显示之类的操作。
我的问题是我应该采取什么方法?其中之一,还是完全不同的东西?我非常喜欢使用命名管道,然后使用 Perl 脚本来打开 FIFO 并根据需要进行读写的想法,因为它提供了很大的灵活性,但从我读到的内容来看,如果我沿着这条路走下去。
提前致谢。
I have inherited a 20-year-old interactive command-line unix application that is no longer supported by its vendor. We need to automate some tasks in this application.
The most troublesome of these is creating thousands of new records with slightly different parameters (e.g. different identifiers, different names). The records have to be created in sequence, one at a time, which would take many months (and therefore dollars) to do manually. In most cases, creating a record has a very predictable pattern of keying in commands, reading responses, keying in further commands, etc. However, some record creation operations will result in error conditions ('record with this identifier already exists') that require a different set of commands to be exit gracefully.
I can see a few different ways to do this:
Named pipes. Write a Perl script that runs the target application with STDIN and STDOUT set to named pipes then sends the target application the sequence of commands to create a record with the required parameters, and then instructs the target application to exit and shut down. We then run the script as many times as required with different parameters.
Application. Find another Unix tool that can be used to script interactive programs. The only ones I have been able to find though are expect, but this does not seem top be maintained; and chat, which I recall from ages ago, and which seems to do more-or-less what I want, but appears to be only for controlling modems.
One more potential complication: I think the target application was written for a VT100 terminal and it uses some sort of escape sequences to do things like provide highlighting.
My question is what approach should I take? One of these, or something completely different? I quite like the idea of using named pipes and then having a Perl script that opens the FIFOs and reads and writes as required, as it provides a lot of flexibility, but from what I have read it seems like there's a lot of potential problems if I go down this path.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如混乱所暗示的那样,我肯定会坚持使用 Perl 以获得额外的灵活性。您知道
Expect
perl 模块吗?它比命名管道方法好得多。另请注意,对于命名管道,您无法强制从旧应用程序返回的输出不被缓冲,这可能会很烦人。我认为 Expect.pm 使用伪 ttys 来解决这个问题,但我不确定。请参阅
perlipc
中的讨论在“与另一个进程的双向通信”部分中了解更多详情。I'd definitely stick to Perl for the extra flexibility, as chaos suggested. Are you aware of the
Expect
perl module? It's a lot nicer than the named pipe approach.Note also with named pipes, you can't force the output coming back from your legacy application to be unbuffered, which could be annoying. I think Expect.pm uses pseudo-ttys to get around this problem, but I'm not sure. See the discussion in
perlipc
in the section "Bidirectional Communication with Another Process" for more details.expect
比您想象的要可靠得多,但如果我是您,我仍然会选择 Perl 选项,希望有一种完整且熟悉的编程语言来管理过程并相信无论出现什么奇怪的问题,都会有办法解决它们。expect
is a lot more solid than you're probably giving it credit for, but if I were you I'd still go with the Perl option, wanting to have a full and familiar programming language for managing the process and having confidence that whatever weird issues arise, there will be ways of addressing them.Expect,无论是使用 Tcl 还是 Perl 实现,将是我的第一次尝试。如果您在输出中看到奇怪的序列,因为它正在执行奇怪的终端操作,只需在进行匹配之前从输出中过滤掉这些序列即可。
无论如何,使用命名管道,您最终都会重新发明 Expect。
Expect, either with the Tcl or Perl implementations, would be my first attempt. If you are seeing odd sequences in the output because it's doing odd terminal things, just filter those from the output before you do your matching.
With named pipes, you're going to end up reinventing Expect anyway.