rguides

system

system(command, intern = FALSE, ignore.stdout = FALSE, ignore.stderr = FALSE, wait = TRUE, input = NULL, show.output.on.console = TRUE, minimized = FALSE, invisible = TRUE, timeout = 0)

The system() function runs an operating system command from within R and returns the command’s exit status or captured output. It is a base R function available on all platforms. While system2() offers a more portable and flexible interface, system() remains widely used for simple command invocations.

Syntax

system(command, intern = FALSE,
       ignore.stdout = FALSE, ignore.stderr = FALSE,
       wait = TRUE, input = NULL,
       show.output.on.console = TRUE, minimized = FALSE,
       invisible = TRUE, timeout = 0)

Parameters

ParameterTypeDefaultDescription
commandcharacterRequiredThe OS command to execute, as a character string
internlogicalFALSEIf TRUE, capture the command’s output as an R character vector
ignore.stdoutlogicalFALSEIf TRUE, discard output written to stdout
ignore.stderrlogicalFALSEIf TRUE, discard output written to stderr
waitlogicalTRUEIf TRUE, wait for the command to finish before continuing
inputcharacterNULLA character vector piped to the command’s standard input
show.output.on.consolelogicalTRUEWindows-only: display output on the Rgui console
minimizedlogicalFALSEWindows-only: launch the command minimized
invisiblelogicalTRUEWindows-only: keep the command window hidden
timeoutnumeric0Maximum seconds to wait before terminating the command

Return Value

The return type depends on the intern argument:

  • intern = FALSE: Returns an integer exit code. 0 means success. 127 means the command could not be run. The value is invisible, so you must print it explicitly to see it.

  • intern = TRUE: Returns a character vector containing the command’s output, one element per line. If the command exits with a non-zero status, the result includes a warning and the exit code is stored in the status attribute.

Platform Differences

The behavior of system() differs significantly between Unix-like systems and Windows.

Unix/Linux/macOS: The command is passed to a shell (typically /bin/sh), so you can use shell features like pipes, redirection, and multiple commands separated by ;.

Windows: The command runs directly without a shell. Use shell() if you need shell features on Windows.

This means the following works on Unix but not Windows:

# Unix: reads stderr alongside stdout
system("grep 'warning' myfile.log 2>&1", intern = TRUE)

On Windows, you need system2() or shell() for equivalent functionality.

Capturing Command Output

Use intern = TRUE to capture output as an R character vector instead of printing it to the console.

# Capture the output of the ls command
result <- system("ls -la", intern = TRUE)
class(result)
# [1] "character"

# First few lines of output
head(result)
# [1] "total 24 drwxr-xr-x  5 user user 4096 Mar 24 04:00 ."         
# [2] "drwxr-xr-x  3 user user 4096 Mar 24 04:00 .."
# [3] "-rw-r--r--  1 user user  220 Mar 23 13:00 .bashrc"

Checking Command Exit Status

When intern = FALSE, system() returns the exit code. Always check this for errors in production scripts.

# Check if a command succeeded
exit_code <- system("mkdir -p output/data")
if (exit_code != 0) {
  warning("Failed to create output directory")
}

# Check if an executable exists
cmd_exists <- function(cmd) {
  system(cmd, intern = FALSE, ignore.stdout = TRUE, ignore.stderr = TRUE) == 0
}

cmd_exists("python3")
# [1] TRUE

cmd_exists("nonexistent_command_xyz")
# [1] FALSE

Passing Input to Commands

Use the input argument to send data to a command’s standard input.

# Send text to a command's stdin
lines <- c("first line", "second line", "third line")
system("wc -l", input = lines)
# 3

Running Commands Asynchronously

Set wait = FALSE to run a command in the background and return immediately.

# Launch a long-running process without blocking
system("sleep 60", wait = FALSE)

# The R session continues without waiting for sleep to finish
print("This prints immediately")
# [1] "This prints immediately"

Handling Timeouts

Use the timeout argument to prevent commands from running indefinitely.

# If this takes more than 5 seconds, it will be killed
result <- system("curl -s https://httpbin.org/delay/10",
                 timeout = 5, intern = TRUE)
# Warning: running command 'curl -s https://httpbin.org/delay/10' had timeout 5
#attr(,"status")
#[1] 124

Exit status 124 indicates the command was terminated by timeout.

Redirecting stderr

On Unix systems, you can capture stderr using shell redirection within the command string.

# Capture both stdout and stderr combined
combined <- system("echo 'out' && echo 'err' >&2", intern = TRUE)
combined
# [1] "out" "err"

To capture them separately on Unix:

# Run a command and capture stdout, ignoring stderr
system("some_command 2>/dev/null", intern = TRUE)

Common Mistakes

Assuming commands work the same across platforms. Shell features like pipes and redirection work on Unix but not Windows. For cross-platform scripts, prefer system2() with explicit argument handling.

Forgetting that return values are invisible. When intern = FALSE, the exit code is returned invisibly. You must wrap in print() or assign to a variable to see it.

Not checking exit codes in automation scripts. A non-zero exit code means the command failed. Ignoring this is a common source of silent failures in production R scripts.

Passing unquoted paths with spaces. On Unix, paths with spaces must be quoted in the command string, just as you would in a shell. The function does not do this automatically.

# Wrong - shell splits on spaces, so "ls My Documents" runs ls with
# two arguments: "My" and "Documents"
system("ls My Documents")

# Correct - use shQuote to properly quote the path
system(paste("ls", shQuote("My Documents")))

See Also

  • readline() — read interactive user input from the console
  • Sys.sleep() — pause R execution for a given number of seconds
  • cat() — write output to the R console