Reputation: 29790
I'd like to send a string to a subprocess's standard input stream, as I might do in Perl 5 like this:
pipe *READ, *WRITE;
if (my $pid = fork()) {
close READ;
print WRITE "Hello world!\n";
close WRITE;
} else {
close WRITE;
open STDIN, '<&=' . fileno READ;
close READ;
exec 'cat';
}
What's the equivalent construction in Raku?
I can send any input to a an external cat
process to get it back in a stream I can pass to yet another process, but that's just terrible.
I've found this Raku module that seems relevant, but it has "Input as well as output" as a TODO, so it doesn't help me now.
There's also this question on this very site that matches this one closely. That author asked for a solution that doesn't rely on an external process, as I am, but the accepted solution still uses an external process.
Finally, I note the docs for Raku's IO::Pipe
class, which seems like it should fit the bill. However, that page says:
Pipes can be easily constructed with sub run and Proc::Async.new.
...which I explicitly want to avoid. I tried just creating a new IO::Pipe
object, hoping I could use its in
and out
streams in a natural way, but I get:
> my $pipe = IO::Pipe.new
Required named parameter 'on-close' not passed
in block <unit> at <unknown file> line 1
That parameter is not mentioned on the doc page, so I suppose I've ventured into undefined territory here.
Upvotes: 11
Views: 297
Reputation: 29790
So this turned out to be embarrassingly easy. Just provide a boolean True
value for run
's in
parameter, then access the resulting process's in
field and write to it.
my $proc = run 'my-command', 'and', 'args', :in;
$proc.in.say('Hello world!');
$proc.in.close;
Upvotes: 10