in reply to Expect and PTY dropping data

Or, is there any way in Expect to get rid of the PTY once the interactive phase is over, using a regular pipe for the rest of the IPC?

Yes, there is, I have found it!

This code spawns a new process with its STDIN and STDOUT redirected to regular pipes/sockets and also attaches a PTY to the child to simulate manual interaction that is handled by Expect.

my $pty = IO::Pty->new; my $expect = Expect->init($pty); my $child = open2($in, $out, '-'); if (defined $child and !$child) { $pty->make_slave_controlling_terminal; exec @cmd; exit -1; } unless (defined $child) { die "unable to spawn new process"; } $expect->expect($timeout, "..."); ... # and once the authentication phase is over, $in and $out are used for + the rest of the IPC.

Also, I have to retain the PTY open until the child program finishes (not just after the authentication is over), otherwise, it gets a SIGPIPE and exits.

Passing a dash (-) to open2 (from IPC::Open2 or open3 from IPC::Open3), makes it fork the current Perl process instead of running an external program.