PHPackages                             esokullu/expect - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. esokullu/expect

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

esokullu/expect
===============

Script interactions with interactive terminal applications.

v0.1.0(10y ago)0231MITPHPPHP &gt;=5.4.0

Since Mar 29Pushed 3y agoCompare

[ Source](https://github.com/esokullu/expect)[ Packagist](https://packagist.org/packages/esokullu/expect)[ RSS](/packages/esokullu-expect/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependencies (3)Versions (2)Used By (0)

Expect
======

[](#expect)

This package is a pure PHP alternative to [expect](https://en.wikipedia.org/wiki/Expect), the Unix tool. This package doesn't depend on the [PECL package](https://pecl.php.net/package/expect) either.

Expect lets you script interactions with interactive terminal applications.

Why?
----

[](#why)

I wrote this because I wrote an interactive CLI program and needed to write automated tests for it. Apparently people use the real expect for scripting ftp and telnet workflows, so I guess you could use it for that too.

Installation
------------

[](#installation)

```
composer require yuloh/expect
```

API
---

[](#api)

Note: all methods return $this for fluent chaining.

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

Spawn a new instance of expect for the given command. You can optionally specify a working directory and a PSR compatible logger to use.

```
expect(string $output, $timeout = 9999999)
```

Expect the given text to show up on stdout. Expect will block and keep checking the stdout buffer until your expectation shows up or the timeout is reached, whichever comes first.

You can use [shell wildcards](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm) to match parts of output.

```
send(string $msg)
```

Send the given text on stdin. A newline is added to each string to simulate pressing enter. If you want to just send enter you can do `send(PHP_EOL)`

Examples
--------

[](#examples)

### Simple Example

[](#simple-example)

This example opens `cat` without any arguments, which will simply echo back everything you type to it.

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

### Npm init

[](#npm-init)

This example demonstrates creating a new package.json with npm. Globs are used to match the expectations so we don't need to type them exactly.

```
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();
```

Logging
-------

[](#logging)

You will probably need logging to figure out what is happening. Expect accepts a PSR compatible logger during instantiation. You can use the `Yuloh\Expect\ConsoleLogger` for readable output while writing scripts or debugging. For example, instantiating Expect like this:

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

...would output this to the terminal:

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

Exceptions
----------

[](#exceptions)

There are a couple of things that can go wrong while running your process:

- The process can fail to start.
- The process can timeout before your expectation happens.
- The process can halt unexpectedly.
- The process can send EOF before your expectation happens.

If the process fails to start, a `RuntimeException` is thrown. The [`Yuloh\Expect\Exceptions` namespace](src/Exceptions) contains exceptions for the other three scenarios. All of the exceptions extend `Yuloh\Expect\FailedExpectationException` so you can just catch that one if you like.

Buffering
---------

[](#buffering)

Some programs like Composer buffer the output so Expect won't work unless you unbuffer the output. The easiest way to do this is probably using [script](https://en.wikipedia.org/wiki/Script_(Unix)). Modify your command to pipe through script like this:

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

Then you can pass that in to Expect:

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

You will probably need to modify expectations when using script, since what you type will show up in stdout too.

Testing
-------

[](#testing)

```
composer test
composer cs
```

###  Health Score

23

—

LowBetter than 26% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

3748d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a3b6d80630289b910b490ff8998d30fd7a83e346ee6568e91c5df5eaae64d294?d=identicon)[esokullu](/maintainers/esokullu)

---

Top Contributors

[![esokullu](https://avatars.githubusercontent.com/u/19166?v=4)](https://github.com/esokullu "esokullu (2 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/esokullu-expect/health.svg)

```
[![Health](https://phpackages.com/badges/esokullu-expect/health.svg)](https://phpackages.com/packages/esokullu-expect)
```

###  Alternatives

[symfony/lock

Creates and manages locks, a mechanism to provide exclusive access to a shared resource

514139.2M692](/packages/symfony-lock)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.7k38.9k](/packages/matomo-matomo)[ecotone/ecotone

Enterprise architecture layer for Laravel and Symfony — CQRS, Event Sourcing, Durable Workflows (Sagas, Orchestrators), Projections, and Outbox messaging via PHP attributes.

564576.7k53](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

751291.4k43](/packages/civicrm-civicrm-core)[illuminate/broadcasting

The Illuminate Broadcasting package.

7127.2M208](/packages/illuminate-broadcasting)[logiscape/mcp-sdk-php

Model Context Protocol SDK for PHP

368116.8k12](/packages/logiscape-mcp-sdk-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
