--- name: exec signature: 'exec LIST' signatures: - 'exec LIST' - 'exec PROGRAM LIST' - 'exec {PROGRAM} LIST' since: 5.0 status: documented categories: ["Processes"] --- ```{index} single: exec; Perl built-in ``` *[Processes](../perlfunc-by-category)* # exec Abandon this program and run another in the same process. `exec` replaces the current process image with another program. It does **not** return on success — execution continues in the new program, with the same process id, open filehandles subject to the close-on-exec flag, and whatever environment was in effect. It returns false (and sets [`$!`](../perlvar)) only when the target could not be launched *and* it was executed directly rather than through the shell. Reach for [`system`](system) when you want the child to run and control to come back. ## Synopsis ```perl exec LIST exec PROGRAM LIST exec { PROGRAM } LIST ``` ## What you get back Nothing, on success — the process has been replaced and this Perl interpreter is gone. On failure `exec` returns false and leaves the reason in [`$!`](../perlvar). Failure is only detectable for the direct-exec path; when the argument is handed to the shell, a missing program is reported by the shell itself and `exec` still counts as having "succeeded" in launching `/bin/sh`. ```perl exec '/usr/bin/vi', $file or die "couldn't exec vi: $!"; ``` Because `exec` normally does not return, Perl emits a warning under `use warnings` if it appears in void context followed by another statement that is not [`die`](die), [`warn`](warn), or [`exit`](exit). Either handle the failure inline with `or die`, or wrap the call in a block to silence the warning: ```perl exec('foo') or die "couldn't exec foo: $!"; { exec('foo') }; die "couldn't exec foo: $!"; ``` ## Shell or no shell — the single-string rule `exec` picks between two launch mechanisms based on the shape of `LIST`: - **Two or more arguments** → `exec` calls `execvp(3)` directly with the list. No shell is involved, no metacharacter interpretation, no word splitting. - **Exactly one argument** → `exec` scans that single string for shell metacharacters. If any are found, the whole string is passed to `/bin/sh -c` for parsing. If none are found, the string is split on whitespace and handed to `execvp` directly. The rule matters for both correctness and security. A one-argument string containing a space but no metacharacters is split into words and executed directly — which is often what you want. A one-argument string containing `|`, `>`, `$`, `;`, glob characters, or quotes goes through the shell, and the shell will happily expand wildcards, interpret variables, and split on `$IFS`. ```perl exec '/bin/echo', 'Your arguments are:', @ARGV; # direct execvp exec "sort $outfile | uniq"; # pipeline → shell exec "ls /tmp"; # no metachars → split + execvp ``` To **force** the no-shell path even with a single logical command, use the indirect-object form described next. ## Indirect-object form — set argv[0], skip the shell Placing a block or scalar before `LIST` (with no comma) tells `exec` two things at once: run *this* program, and pass *those* arguments as `argv`. The first element of `LIST` becomes `argv[0]` — the name the child sees for itself — which need not match the program path. ```perl exec { '/bin/echo' } 'echo', 'hi'; # argv[0] is "echo" my $shell = '/bin/csh'; exec $shell '-sh'; # login-shell convention: argv[0] = "-sh" exec { '/bin/csh' } '-sh'; # same, more direct ``` The indirect-object form always treats `LIST` as a multi-valued list, even if it has only one element. That disables the metacharacter scan entirely: ```perl my @args = ('echo surprise'); exec @args; # one element → shell scan → /bin/sh -c 'echo surprise' exec { $args[0] } @args; # always direct execvp, "echo surprise" is argv[0] ``` In the second form there is no program on disk literally named `echo surprise`, so `execvp` fails, `exec` returns false, and [`$!`](../perlvar) holds the reason. That's the safe behaviour: the caller gets to decide what to do, rather than the shell running something unexpected. ## Global state it touches - [`$!`](../perlvar) — set on failure to the `errno` from the underlying `execvp(3)` call. Only meaningful when `exec` actually returns. - [`$?`](../perlvar) — left unchanged by `exec` itself, but a failed shell-mediated attempt may leave the shell's exit status visible to a wrapping [`system`](system). - The process's open filehandles, environment ([`%ENV`](../perlvar)), current working directory, [`umask`](umask), signal dispositions, and resource limits all carry into the replacement program — `exec` replaces the program, not the process. ## Examples Run a program with an explicit argument list, direct `execvp`: ```perl exec '/usr/bin/git', 'status', '--short' or die "exec git: $!"; ``` Hand a command line to the shell deliberately, using metacharacters: ```perl exec "find . -name '*.tmp' -print0 | xargs -0 rm" or die "exec pipeline: $!"; ``` Set a distinctive `argv[0]` so the child's `ps` line identifies its role: ```perl exec { '/usr/local/bin/worker' } 'worker[queue=email]', @flags or die "exec worker: $!"; ``` Fork-and-exec — the classic pattern for launching a child without replacing yourself: ```perl my $pid = fork // die "fork: $!"; if ($pid == 0) { exec '/usr/bin/gzip', '-9', $file or die "exec gzip: $!"; } waitpid $pid, 0; ``` Guarantee the no-shell path when the argument list was assembled from data: ```perl my @cmd = build_command(); # may contain one element or many exec { $cmd[0] } @cmd or die "exec $cmd[0]: $!"; ``` ## Edge cases - **Never returns on success.** Any code after a bare `exec` is reachable only on failure. Under `use warnings`, a following statement other than [`die`](die), [`warn`](warn), or [`exit`](exit) triggers a warning — Perl's hint that you probably meant [`system`](system). - **Single-argument trap.** `exec $cmd` where `$cmd` came from user input is a shell-injection vector if `$cmd` contains metacharacters. Use the indirect-object form or pass a pre-split list. - **Output buffering.** Perl attempts to flush handles opened for output before handing control to the new program, but this is not guaranteed on every platform. If you have pending output on an unflushed handle, set [`$|`](../perlvar) on the selected handle — or call the `autoflush` method on each `IO::Handle` — before `exec`. - **`END` blocks and `DESTROY`.** `exec` does **not** run `END` blocks, and it does **not** invoke `DESTROY` on your objects. The process image is replaced; Perl-level cleanup never happens. Anything that needs a clean shutdown (temp files, lockfile removal, buffered log flushes) must happen before `exec`. - **Close-on-exec.** Filehandles with the `FD_CLOEXEC` flag set are closed by the kernel during `execvp`; others stay open. Control this with `fcntl` or the `$^F` system filehandle threshold. - **Shell-mediated failure is invisible.** When `exec` routes through `/bin/sh -c`, a missing target program is reported by the shell and `exec` itself has already been replaced by `/bin/sh`. Your Perl code will not see a failure return. - **One-arg list with no metacharacters** is *still* split on whitespace and passed to `execvp` — so `exec "ls /tmp"` is a direct exec of `/bin/ls` with one argument, not a shell call. - **Empty `LIST`** is a runtime error; there is no program to run. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`system`](system) — run a program and wait for it; what you almost certainly wanted if `exec` is at the top of the file - [`fork`](fork) — pair with `exec` in the child to launch a program without replacing the parent - [`wait`](wait) — collect a child produced by `fork` + `exec` - [`die`](die) — terminate the current program with an error; the idiomatic partner of `exec ... or die` - [`$!`](../perlvar) — error reason set when direct-exec fails - [`$|`](../perlvar) — autoflush flag; set before `exec` so no buffered output is lost when the process image is replaced