When running a command with exec
, the parent shell will exit upon the command finishes running. How can I tell if a command executed by exec
runs successfully or not?
3 Answers
When you successfully use exec
, the exec
'd program replaces your shell. The exec
'd program's exit status is sent back to the parent process that executed your shell.
The only way that exec's exit status can be interpreted by the line following exec
is if the exec calls fails, normally only if the command requested does not exist or if the file is not executable. This does not include option parsing problems, since those are parsed by the exec'd program once it is started.
If you want your shell to interpret the exit code of a program, you cannot use exec
to do it. Just run the program in your shell, and when it finishes you can consult the exit status.
For more information, you can consult man 3 exec
, this or one of its sister functions is the basic low-level Unix function that your shell calls.
The only reasonable reason I can think of to use exec
from your shell command line is on an extremely low-memory machine where the memory used by the shell is a problem, or on a machine subject to forking problems where you are very lucky to have a shell, you cannot fork any new process, and you only need that one new process to correct the problem.
Normal uses of exec are in shell scripts, for example
(thanks @chicks) in a login script that delegates the console to a less-trusted user; when the application terminates there is no chance that the user will gain control of your shell
in a shell script that just sets preconditions (environment, ulimit) for the exec'd program, and you want the return code of the exec'd program to return directly to whoever called your script. Since the exec'd process is the same PID, the script can record that.
-
1See Use case / practical example for the shell's
exec
builtin for more examples. Apr 19, 2016 at 21:10
According to the exec man page:
If command is specified,
exec
shall not return to the shell …
So you can have some code after exec
.
If this code is reached, something has gone wrong.
exec foo
ret=$?
## foo was not executed.
otherwise the calling script of the shell calling exec
might get status from the foo
command.
e.g., bash1
calls bash2
, bash2
calls exec foo
as above.
In this case, bash1
will get the return code from foo
.
bash2
will get any error from the call to exec foo
.
You can use the exit status of the command executed by exec
to see if it worked or not, provided that command does sensible things with its own exit status, and what you want to know is simple enough to encode in an exit status.
It looks to me like the bash
exec
preserves stdout and stderr of the executed command. I think you can use the output of the command executed by exec
to see if it worked or not.
It also looks to me like bash
checks permissions of the command to be executed, so you get some output if you give it a file that does not have execute or read permissions.
-
1You write, "You can use the exit status of the command executed by exec to see if it worked or not". The parent can see this exit status. The process that called
exec
will only continue if theexec
itself failed. Once theexec
has started a replacement program there is nothing left of the calling process. I suspect that's what you meant but it isn't clear.– roaimaApr 17, 2016 at 7:29
exec
if you need the exit status? There might be a good reason for this, I just can't think of one.