Programs running other programs and communicating with them
Many programs need to be able to run other programs, and we need to pass information to them and receive their output and exit status. Running a program in Raku is as easy as:
run 'git', 'status';
This line runs the program named "git" and passes "git" and "status" to its command-line. It will find the program using the
If you would like to run a program by sending a command-line to the shell, there's a tool for that as well. All shell metacharacters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on.
shell 'ls -lR | gzip -9 > ls-lR.gz';
Caution should be taken when using
shell with user input.
shell return a Proc object, which can be used to communicate with the process in more detail. Please note that unless you close all output pipes, the program will usually not terminate.
my = run 'git', 'log', '--oneline', :out;for .out.lines ->.out.close();
If the program fails (exits with a non-zero exit code), it will throw an exception when the returned Proc object is sunk. You can save it into a variable, even anonymous one, to prevent the sinking:
$ = run '/bin/false'; # does not sink the Proc and so does not throw
You can tell the
Proc object to capture output as a filehandle by passing the
:err flags. You may also pass input via the
my = run 'echo', 'Hello, world', :out;my = run 'cat', '-n', :in(.out), :out;say .out.get;.out.close();
You may also use
Proc to capture the PID, send signals to the application, and check the exitcode.
my = run 'crontab', '-l';if .exitcode == 0else
When you need more control over the communication with and from another process, you will want to make use of Proc::Async. This class provides support for asynchronous communication with a program, as well as the ability to send signals to that program.
# Get ready to run the programmy = Proc::Async.new('tail', '-f', '/var/log/system.log');.stdout.tap(-> );.stderr.tap(-> );# Start the programmy = .start;sleep 10;# Tell the program to stop.kill('QUIT');# Wait for the program to finishawait ;
The small program above uses the "tail" program to print out the contents of the log named
system.log for 10 seconds and then tells the program to stop with a QUIT signal.
Proc provides access to output using
Proc::Async provides access using asynchronous supplies (see Supply).
If you want to run a program and do some work while you wait for the original program to finish, the
start routine returns a Promise, which is kept when the program quits.
write method to pass data into the program.