I ran into a situation recently where I needed a Perl script to launch another program, wait for it to finish, and move on. Nothing fancy. A simple spawn-and-wait. But doing it the naive way — backticks, pipe reads, polling — felt like overkill for what should be a two-liner.

That’s where the Expect module comes in. It’s been around since the 90s, originally ported from the Tcl expect tool, and it does exactly what you’d expect: it spawns a process, talks to its stdin, reads its stdout, and waits for specific patterns. For simple cases it’s overkill. For anything that involves an interactive prompt or a non-trivial exit condition, it saves you from writing your own state machine.

Here’s the simplest possible example.

First, a target script — hello.pl:

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

print "-----------\n",
      "Hello World\n",
      "-----------\n";

Nothing special. It prints three lines and exits. Now the driver script, test.pl:

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Expect;

my $timeout = 5;
for my $i (1..20) {
    my $exp = Expect->spawn("./hello.pl")
        or die "Couldn't spawn the process: $!\n";
    $exp->expect($timeout);
}

The loop runs the spawned script 20 times. Each iteration creates a new Expect object, spawns hello.pl, and waits up to 5 seconds for it to finish. If the process doesn’t exit within the timeout, expect returns without throwing — it just stops waiting. That’s worth keeping in mind: a timeout isn’t a failure, it’s a signal that something might be stuck.

The use diagnostics line is worth keeping while you’re learning. It turns Perl’s terse error messages into full explanations with context. Once you’re comfortable, you can drop it. use strict and use warnings stay forever.

This is the bare minimum. The real power of Expect shows up when you need to match output patterns, send input in response to prompts, or chain multiple interactions together. But if all you need is “run this thing and wait for it to be done”, this is enough to get started.