#!/usr/bin/perl use strict; use warnings; use IPC::Open3; use IO::Select; my @cmd = qw'echo bar'; # writing to 'echo' fails #my @cmd = qw'cat'; # ... while 'cat' works open3(my $wh, my $rh, undef, @cmd); # tiny delay, so the command gets enough time to close STDIN # (prevent potential race condition, in this demo script) select undef,undef,undef, 0.1; my $msg = "foo"; #----- print $wh "$msg\n"; close $wh; #----- my $data = ""; if (IO::Select->new($rh)->can_read()) { print "reading from $rh ('@cmd |')\n"; while (sysread($rh, my $buffer, 1000)) { $data .= $buffer; } } print "data: $data\n"; #### #----- # handle SIGPIPE ourselves, so we don't get killed $SIG{PIPE} = sub { warn "BROKEN PIPE\n" }; if (my ($w) = IO::Select->new($wh)->can_write()) { if (print $w "$msg\n") { print "wrote '$msg' to $w ('| @cmd')\n"; close $w; } else { warn "print to $w FAILED\n"; # we'll have gotten a SIGPIPE, too } } else { warn "$wh not ready for writing\n"; } #----- #### BROKEN PIPE print to GLOB(0x6ff5b0) FAILED reading from GLOB(0x6ff360) ('echo bar |') data: bar #### wrote 'foo' to GLOB(0x63c160) ('| cat') reading from GLOB(0x6ff5a0) ('cat |') data: foo #### GLOB(0x6ff5b0) not ready for writing reading from GLOB(0x6ff360) ('echo bar |') data: bar