System interaction

Working with the underlying operating system and running applications

Getting arguments through the command line

The simplest way is to use the @*ARGS variable to obtain arguments from the command line; this array will contain the strings that follow the program name. %*ENV will contain the environment variables, so that if you use:

export API_KEY=1967196417966160761fabc1511067
./consume_api.p6

You can use them from your program this way:

my $api-key = %*ENV<API_KEY> // die "Need the API key";

This will fail if the environment variable API_KEY has not been defined previously.

Raku has a better way to deal with command line arguments if they represent file names: the $*ARGFILES dynamic variable.

for $*ARGFILES.lines -> $l {
    say "Long lines in {$*ARGFILES.path}"
        if $l.chars > 72 ;
}

You can run this program this way argfiles.p6 *.p6, for instance, and it will print a file name every time it finds a line longer than 72 characters. $*ARGFILES contains filehandles of all files described in the command lines- .lines will read in turn one line from every one of them, changing the value of $*ARGFILES.path every time a new handle is being processed. In general, it provides a very convenient API for scripts that deal with sets of files.

Getting arguments interactively

Use prompt to have a running program query the user for data:

my UInt $num-iters = prompt "How many iterations to run: ";

Running programs synchronously and asynchronously

There are two routines to run external programs: run and shell. Both exist in the IO role and are thus included in all classes that mix that role in, like IO::Path. Both return a Proc object, but the main difference is that run will try to avoid the system shell, if possible, while shell will run the command through the default system shell.

The key class for running all external programs is Proc::Async, which runs processes asynchronously and allows concurrent interaction with the running processes. In general, it is a good practice to interact with the system through these high-level, abstract interfaces. However, Raku provides with other ways of interacting with the system through a low-level interface.

Making operating system calls through the native API

The NativeCall API can be used to interact with system libraries, as well as any other accessible library. This short tutorial explains, for instance, how to call system functions such as getaddrinfo using that interface; some other functions like kill can also be accessed that way, via declaration using the NativeCall interface.

Fortunately, you do not have to do that for all native functions. As part of her Butterfly project porting Perl functions to Raku as part of the ecosystem, Elizabeth Mattijsen is porting many system functions that were part of that language to modules such as P5getprotobyname, which includes functions such as endprotoent, getprotoent, getprotobyname, getprotobynumber and setprotoent. Search and install P5 modules if you want to use those functions already in Raku.