esokullu/expect

脚本与交互式终端应用程序的交互。

v0.1.0 2016-03-29 06:03 UTC

This package is not auto-updated.

Last update: 2024-09-29 06:20:36 UTC


README

本软件包是Unix工具expect的纯PHP替代品。此软件包也不依赖于PECL软件包

Expect 允许您与交互式终端应用程序进行脚本交互。

为什么?

我编写这个软件包是因为我编写了一个交互式CLI程序,并需要为其编写自动化测试。显然,人们使用真正的expect进行ftp和telnet工作流程的脚本编写,所以我想你也可以用它来做这个。

安装

composer require yuloh/expect

API

注意:所有方法都返回 $this 以实现流畅的链式调用。

spawn(string $cmd, string $cwd = null, LoggerInterface $logger = null)

为给定的命令启动expect的新实例。您可以可选地指定工作目录和要使用的PSR兼容的日志记录器。

expect(string $output, $timeout = 9999999)

期望给定文本出现在stdout上。Expect将阻塞并持续检查stdout缓冲区,直到期望出现或达到超时,以先到者为准。

您可以使用shell通配符来匹配输出的一部分。

send(string $msg)

在stdin上发送给定的文本。每个字符串都添加换行符以模拟按下enter键。如果您只想发送enter,则可以这样做 send(PHP_EOL)

示例

简单示例

此示例不添加任何参数打开cat,它将简单地回显您输入的所有内容。

Yuloh\Expect\Expect::spawn('cat')
    ->send('hi')
    ->expect('hi')
    ->send('yo')
    ->expect('yo')
    ->run();

Npm init

此示例演示使用npm创建新的package.json。我们使用Glob来匹配期望,因此我们不需要精确地输入它们。

Yuloh\Expect\Expect::spawn('npm init')
    ->expect('*name:*')
    ->send('package')
    ->expect('version*')
    ->send('1.0.0')
    ->expect('description*')
    ->send('awesome')
    ->expect('entry point*')
    ->send('index.js')
    ->expect('test command*')
    ->send('test')
    ->expect('git repository*')
    ->send('yuloh/expect')
    ->expect('keywords*')
    ->send('awesome')
    ->expect('author*')
    ->send('matt')
    ->expect('license*')
    ->send('ISC')
    ->expect('*')
    ->send('yes')
    ->run();

日志记录

您可能需要日志记录来了解正在发生的事情。Expect在实例化时接受PSR兼容的日志记录器。您可以使用Yuloh\Expect\ConsoleLogger在编写脚本或调试时获得可读的输出。例如,这样实例化Expect

Yuloh\Expect\Expect::spawn('cat', getcwd(), new Yuloh\Expect\ConsoleLogger())
    ->send('hi')
    ->expect('hi')
    ->run();

...将在终端输出以下内容

* Sending 'hi⏎'
* Expected 'hi', got 'hi'

异常

在运行您的进程时可能会出现一些问题

  • 进程可能无法启动。
  • 在期望发生之前,进程可能已超时。
  • 进程可能意外停止。
  • 在期望发生之前,进程可能已发送EOF。

如果进程无法启动,则会抛出RuntimeException。The Yuloh\Expect\Exceptions 命名空间 包含其他三种情况的异常。所有异常都扩展了 Yuloh\Expect\FailedExpectationException,因此如果您愿意,可以只捕获该异常。

缓冲

一些程序(如Composer)会缓冲输出,因此除非您取消缓冲输出,否则Expect将无法正常工作。最简单的方法可能是使用script。将您的命令修改为通过script管道传递,如下所示

# FreeBSD/Darwin (Mac OSX)
script -q /dev/null {your-command}
# Linux
script -c {your-command} /dev/null

然后您可以将该命令传递给Expect

Expect::spawn('script -q /dev/null ssh localhost')
    ->expect('*password:')
    ->send('hunter 2')
    ->run();

在您使用script时,可能需要修改期望,因为您输入的内容也会显示在stdout上。

测试

composer test
composer cs