Sean
Sean

Reputation: 29790

Raku: Sending a string to a subprocess's standard input

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

Answers (1)

Sean
Sean

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

Related Questions