--- name: system signature: 'system LIST' since: 5.0 status: documented categories: ["Processes"] --- ```{index} single: system; Perl built-in ``` *[Processes](../perlfunc-by-category)* # system Run a separate program and wait for it to finish. `system` does exactly the same thing as [`exec`](exec), except that a [`fork`](fork) is done first and the parent process waits for the child to exit. The return value is the wait status of the child, not its output — if you want the output of a command, use backticks or [`qx//`](qx) instead. ## Synopsis ```perl system LIST system PROGRAM LIST ``` The indirect `PROGRAM LIST` form lies to the program about its own name: `PROGRAM` is the file actually executed, while the first element of `LIST` becomes `argv[0]` inside the child. Same trick as [`exec`](exec). ## What you get back The return value is the raw status word from the underlying [`wait`](wait) call — the same value that lands in [`$?`](../perlvar) after the call. To recover the program's actual exit code, shift right by eight: ```perl system("make", "install"); my $exit = $? >> 8; ``` `-1` means the program could not be started at all (or the `wait` itself failed); inspect [`$!`](../perlvar) for the reason. A return of `0` means the child exited successfully with status `0`. ## Shell-vs-direct execution Argument processing depends on the shape of `LIST`, and mirrors [`exec`](exec) exactly: - **More than one argument** (or an array with more than one element): the first element is the program, the rest are its arguments. The shell is **not** invoked; `execvp` runs the program directly. This is the safe form. - **Exactly one scalar argument**: Perl scans it for shell metacharacters. If any are present, the entire string is passed to `/bin/sh -c` for parsing. If none are present, Perl splits on whitespace and calls `execvp` directly — saving a shell. Prefer the list form whenever the arguments come from untrusted input or contain characters the shell would interpret: ```perl system("ls", "-l", $dir); # safe, no shell system("ls -l $dir"); # shell parses $dir — hazardous ``` ## Signals vs. exit The status word combines three pieces of information: a signal number (if the child died on a signal), a core-dump flag, and the exit value. Decode it explicitly when you need to tell them apart: ```perl system(@cmd); if ($? == -1) { print "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf "child exited with value %d\n", $? >> 8; } ``` For a structured decode, inspect [`${^CHILD_ERROR_NATIVE}`](../perlvar) — the full native status word — with the `WIFEXITED`, `WEXITSTATUS`, `WIFSIGNALED`, `WTERMSIG` macros from `POSIX`: ```perl use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG); system(@cmd); my $n = ${^CHILD_ERROR_NATIVE}; if (WIFEXITED($n)) { my $code = WEXITSTATUS($n); ... } if (WIFSIGNALED($n)) { my $sig = WTERMSIG($n); ... } ``` `SIGINT` and `SIGQUIT` are ignored in the parent while the child runs. If you want your own program to die when the user hits Ctrl-C during `system`, check the return status yourself and re-raise: ```perl system(@cmd); kill 'INT', $$ if ($? & 127) == 2; # re-raise SIGINT on self ``` ## Stdio flushing Before the fork, Perl attempts to flush every filehandle opened for output. This prevents buffered lines from being duplicated by both parent and child. The flush is best-effort; on platforms where it is unreliable, set [`$|`](../perlvar) (`$AUTOFLUSH`) or call the `autoflush` method from `IO::Handle` on handles you care about. ## The die idiom The canonical check — terse, and it embeds the status word in the message so the caller can still decode it: ```perl my @args = ("command", "arg1", "arg2"); system(@args) == 0 or die "system @args failed: $?"; ``` For a module that should throw on any failed `system` (and many other bits of Perl), use the `autodie` pragma. ## Examples Run a command and ignore the result: ```perl system("clear"); ``` Run a command, die on failure, and keep the status intact for downstream inspection: ```perl system("tar", "xf", $archive) == 0 or die "untar $archive failed: $?"; ``` Detect whether a program is available by running it with `--version` and discarding its output: ```perl my $ok = system("which $prog >/dev/null 2>&1") == 0; ``` Run under a specific shell explicitly, bypassing Perl's metacharacter-detection heuristic: ```perl system("/bin/bash", "-c", $pipeline); ``` Lie about `argv[0]` using the indirect form — the kernel executes `/usr/bin/vim`, but the program sees its name as `editor`: ```perl system { "/usr/bin/vim" } "editor", $file; ``` ## Edge cases - **Return of -1**: the child was never created, or [`wait`](wait) itself failed. Distinct from "child exited with status 255". Check [`$!`](../perlvar) for the reason — typically `ENOENT` (program not found) or `EACCES` (not executable). - **Exit value 255 from a shell**: when the shell form is used and `/bin/sh` cannot find the program, the shell itself exits with `127`. Programs that return `255` from Perl typically come through `die` in another Perl program. - **`SIGCHLD` handler interaction**: `system` internally forks and waits. A `$SIG{CHLD}` handler can observe or race with this wait; see `perlipc` for the reaping discipline. - **Shell quirks**: when the shell form is triggered, return codes and error reporting are whatever `/bin/sh` says they are — not always what the underlying program returned. Use the list form to avoid this. - **Not for capturing output**: `system` writes the child's output to the inherited `STDOUT`/`STDERR`. Use [`qx//`](qx) or open a pipe with [`open`](open) if you need the output as a string. - **Windows**: only the `system PROGRAM LIST` syntax reliably avoids the shell. pperl is Linux-only, so this does not apply here; noted for portability. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`exec`](exec) — replace the current process instead of forking and waiting; same argument-processing rules as `system` - [`fork`](fork) — create a child process without running a new program; `system` is `fork` + `exec` + [`waitpid`](waitpid) - [`waitpid`](waitpid) — reap a specific child, used when managing multiple children directly - [`qx`](qx) — run a command and capture its output as a string; what you want when `system`'s stdio targeting is not enough - [`$?`](../perlvar) — child error status word set by `system`, backticks, pipe `close`, and `wait` - [`$!`](../perlvar) — errno after a failed fork or exec (return value `-1`) - [`${^CHILD_ERROR_NATIVE}`](../perlvar) — full native wait status for decoding with `POSIX` `W*` macros