|
| 1 | +=begin pod |
| 2 | +
|
| 3 | +=TITLE Inter-Process Communication |
| 4 | +
|
| 5 | +=SUBTITLE Programs running other programs and communicating with them |
| 6 | +
|
| 7 | +=head1 X<running|running programs> |
| 8 | +
|
| 9 | +Many programs need to be able to run other programs. Running a program in Perl 6 |
| 10 | +is as easy as: |
| 11 | +
|
| 12 | + run 'git', 'status'; |
| 13 | +
|
| 14 | +This line runs the program named "git" and passes "git" and "status" to its |
| 15 | +command-line. It will find the program using the C<< %*ENV<PATH> >> setting. |
| 16 | +
|
| 17 | +If you would like to run a program by sending a command-line to the shell, |
| 18 | +there's a tool for that as well. All shell meta characters are interpreted by |
| 19 | +the shell, including pipes, redirects, environment variable substitutions and so |
| 20 | +on. |
| 21 | +
|
| 22 | + shell 'ls -lR | gzip -9 > ls-lR.gz'; |
| 23 | +
|
| 24 | +Caution should be taken when using C<shell> with user input. |
| 25 | +
|
| 26 | +=head1 X<proc|Proc object> |
| 27 | +
|
| 28 | +Both C<run> and C<shell> return a L<Proc|/type/Proc> object, which can be used |
| 29 | +to communicate with the process in more detail. |
| 30 | +
|
| 31 | + my $git = run 'git', 'log', '--oneline', :out; |
| 32 | + for $git.out.lines -> $line { |
| 33 | + my ($sha, $subject) = $line.split: ' ', 2; |
| 34 | + say "$subject [$sha]"; |
| 35 | + } |
| 36 | +
|
| 37 | +You can tell the C<Proc> object to capture output as a file handle by passing |
| 38 | +the C<:out> and C<:err> flags. You may also pass input via the C<:in> flag. |
| 39 | +
|
| 40 | + my $echo = run 'echo', 'Hello, world', :out; |
| 41 | + my $cat = run 'cat', '-n', :in($echo.out), :out; |
| 42 | + say $cat.out.get; |
| 43 | +
|
| 44 | +You may also use C<Proc> to capture the PID, send signals to the application, |
| 45 | +and check the exitcode. |
| 46 | +
|
| 47 | + my $crontab = run 'crontab' '-l'; |
| 48 | + if $crontab.exitcode == 0 { |
| 49 | + say 'crontab -l ran ok'; |
| 50 | + } |
| 51 | + else { |
| 52 | + say 'something went wrong'; |
| 53 | + } |
| 54 | +
|
| 55 | +=head1 X<async|Proc::Async object> |
| 56 | +
|
| 57 | +When you need more control over the communication with and from another process, |
| 58 | +you will want to make use of L<Proc::Async|/type/Proc::Async>. This class |
| 59 | +provides support for asynchronous communication with a program, as well as the |
| 60 | +ability to send signals to that program. |
| 61 | +
|
| 62 | + # Get ready to run the program |
| 63 | + my $log = Proc::Async.new('tail', '-f', '/var/log/system.log'); |
| 64 | + $log.stdout.tap(-> $buf { print $buf }); |
| 65 | + $log.stderr.tap(-> $buf { $*ERR.print $buf }); |
| 66 | +
|
| 67 | + # Start the program |
| 68 | + my $done = $proc.start; |
| 69 | + sleep 10; |
| 70 | +
|
| 71 | + # Tell the program to stop |
| 72 | + $log.kill('QUIT'); |
| 73 | +
|
| 74 | + # Wait for the program to finish |
| 75 | + await $done; |
| 76 | +
|
| 77 | +Here is a small program that uses the "tail" program to print out the contents |
| 78 | +of the log named F<system.log> for 10 seconds and then tells the program to stop |
| 79 | +with a QUIT signal. |
| 80 | +
|
| 81 | +Whereas C<Proc> provides access to output using C<IO::Handle>s, C<Proc::Async> |
| 82 | +provides access using asynchronous supplies (see L<Supply|/type/Supply>). |
| 83 | +
|
| 84 | +If you want to run a program and do some work while you wait for the original |
| 85 | +program to finish, the C<start> routine returns a L<Promise|/type/Promise>, |
| 86 | +which is kept when the program quits. |
| 87 | +
|
| 88 | +Use the C<write> method to pass data into the program. |
| 89 | +
|
| 90 | +=end pod |
| 91 | + |
| 92 | +# vim: expandtab shiftwidth=4 ft=perl6 |
0 commit comments