R: Running System Commands

exec {sys} | R Documentation

## Running System Commands

### Description

Powerful replacements for system2 with support for interruptions, background tasks and fine grained control over `STDOUT` / `STDERR` binary or text streams.

### Usage

    exec_wait(cmd, args = NULL, std_out = stdout(), std_err = stderr(),
      std_in = NULL, timeout = 0)

    exec_background(cmd, args = NULL, std_out = TRUE, std_err = TRUE,
      std_in = NULL)

    exec_internal(cmd, args = NULL, std_in = NULL, error = TRUE,
      timeout = 0)

    exec_status(pid, wait = TRUE)

### Arguments

`cmd` | the command to run. Either a full path or the name of a program on the `PATH`. On Windows this is automatically converted to a short path using Sys.which, unless wrapped in `I()`.
`args` | character vector of arguments to pass. On Windows these automatically get quoted using windows_quote, unless the value is wrapped in `I()`.
`std_out` | if and where to direct child process `STDOUT`. Must be one of `TRUE`, `FALSE`, filename, connection object or callback function. See section on Output Streams below for details.
`std_err` | if and where to direct child process `STDERR`. Must be one of `TRUE`, `FALSE`, filename, connection object or callback function. See section on Output Streams below for details.
`std_in` | file path to map std_in
`timeout` | maximum time in seconds
`error` | automatically raise an error if the exit status is non-zero.
`pid` | integer with a process ID
`wait` | block until the process completes

### Details

Each value within the `args` vector will automatically be quoted when needed; you should not quote arguments yourself. Doing so anyway could lead to the value being quoted twice on some platforms.

The `exec_wait` function runs a system command and waits for the child process to exit. When the child process completes normally (either success or error) it returns with the program exit code. Otherwise (if the child process gets aborted) R raises an error. The R user can interrupt the program by sending SIGINT (press ESC or CTRL+C) in which case the child process tree is properly terminated. Output streams `STDOUT` and `STDERR` are piped back to the parent process and can be sent to a connection or callback function. See the section on Output Streams below for details.

The `exec_background` function starts the program and immediately returns the PID of the child process. This is useful for running a server daemon or background process. Because this is non-blocking, `std_out` and `std_out` can only be `TRUE`/`FALSE` or a file path. The state of the process can be checked with `exec_status` which returns the exit status, or `NA` if the process is still running. If `wait = TRUE` then `exec_status` blocks until the process completes (but can be interrupted). The child can be killed with tools::pskill.

The `exec_internal` function is a convenience wrapper around `exec_wait` which automatically captures output streams and raises an error if execution fails. Upon success it returns a list with status code, and raw vectors containing stdout and stderr data (use rawToChar for converting to text).

### Value

`exec_background` returns a pid. `exec_wait` returns an exit code. `exec_internal` returns a list with exit code, stdout and stderr strings.

### Output Streams

The `std_out` and `std_err` parameters are used to control how output streams of the child are processed. Possible values for both foreground and background processes are:

- `TRUE`: print child output in R console

- `FALSE`: suppress output stream

- string: name or path of file to redirect output

In addition the `exec_wait` function also supports the following `std_out` and `std_err` types:

- connection a writable R connection object such as stdout or stderr

- function: callback function with one argument accepting a raw vector (use rawToChar to convert to text).

When using `exec_background` with `std_out = TRUE` or `std_err = TRUE` on Windows, separate threads are used to print output. This works in RStudio and RTerm but not in RGui because the latter has a custom I/O mechanism. Directing output to a file is usually the safest option.

### See Also

Base system2 and pipe provide other methods for running a system command with output.

Other sys: `exec_r`

### Examples

    # Run a command (interrupt with CTRL+C)
    status <- exec_wait("date")

    # Capture std/out
    out <- exec_internal("date")
    print(out$status)
    cat(rawToChar(out$stdout))

    if(nchar(Sys.which("ping"))){

    # Run a background process (daemon)
    pid <- exec_background("ping", "localhost")

    # Kill it after a while
    Sys.sleep(2)
    tools::pskill(pid)

    # Cleans up the zombie proc
    exec_status(pid)
    rm(pid)
    }

[Package sys version 2.1 Index]