exit simply exits the shell, returning the specified numeric exit code (or 0 if omitted) to the parent process. This is equivalent to the C library routine, also called exit , or to return from main .
exec replaces the shell with a new executable image (still running in the same process), which will eventually come out and return some code or another parent process. This is roughly equivalent to the regular C execvp library.
Your first example is an almost, but not quite, correct way to stop a script if an error occurs. He must read
if [ ! -f file ]; then echo "no file" >&2 exit 1 fi
>&2 , which is not in your example, causes an error message in stderr where it belongs, instead of stdout where it does not belong.
The second example is incorrect. In addition to reporting the error in the wrong place, exec echo will stop the script (because /bin/echo will do its job and then exit), but it will return exit code 0 to the parent process. Exit code 0 means success. Programs running on a Unix environment must always return a non-zero exit code if they fail.
The correct use of exec is done in shell scripts that do some configuration work and then call a long-lived program written in another language, and after that they have nothing to do, so it makes no sense to keep the shell process hanging around. For instance:
#! /bin/sh PATH=/special/directory/for/foo:$PATH export PATH exec foo
source share