Shell builtins · bash builtin
false
Do nothing and exit with status 1 (failure).
false
false does nothing and fails: it exits with status 1 and prints nothing. It is the simplest
way to produce a failure on purpose, which is more useful than it sounds: testing how a script
reacts to an error, demonstrating set -e and || chains, or giving an account a "shell" that
refuses to run anything.
Like true, it is a bash builtin and also exists as /usr/bin/false. Any non-zero status
counts as failure in the shell, and false always uses 1.
Examples
Check its exit status
false; echo "exit: $?"
exit: 1
Nothing is printed by false; the status is 1.
Watch && and || react to failure
false && echo "and: ran" || echo "or: ran"
or: ran
&& runs its right side only after success, || only after failure. false skips the
first echo and triggers the second.
Invert a status with !
! false; echo "exit: $?"
exit: 0
The ! keyword negates a pipeline's status, so ! false succeeds.
Stop a script at the first failure
set -e
echo "step 1"
false
echo "step 2"
step 1
Under set -e, the failing false ends the script with its status; step 2 is never printed.
Know where set -e does not apply
set -e
if false; then echo "yes"; else echo "condition failed, script continues"; fi
false || echo "handled with ||"
echo "done"
condition failed, script continues handled with || done
A failure that is being tested (in an if condition, or on the left of || or &&) does
not trigger set -e. That is how scripts handle expected failures while still stopping on
unexpected ones.
See that a pipeline reports its last command
false | true; echo "status: $?"
set -o pipefail
false | true; echo "with pipefail: $?"
status: 0 with pipefail: 1
By default the pipeline's status is the last command's, so the failure is lost. With
pipefail the pipeline fails if any part fails.
Test an error handler
deploy() { false; }
if ! deploy; then
echo "deploy failed, rolling back" >&2
fi
deploy failed, rolling back
Swapping a real command for false is a quick way to exercise the failure path of a script
without breaking anything.
Find accounts whose shell refuses logins
awk -F: '$7 ~ /(false|nologin)$/ { print $1, $7 }' /etc/passwd | head -5
daemon /usr/sbin/nologin bin /usr/sbin/nologin sys /usr/sbin/nologin games /usr/sbin/nologin man /usr/sbin/nologin
Debian gives its system accounts /usr/sbin/nologin as their shell so nobody can log in as
them; older systems and some packages use /bin/false. Both refuse the login: nologin
prints a short message first, false just exits.
Common pitfalls
if [ false ]is true. Inside[ ]the wordfalseis a non-empty string, and non-empty strings test as true. Call the command directly:if false.Expecting
set -eto catch a failing command inside a pipeline or a condition. Addset -o pipefailfor pipelines, and handle tested commands yourself.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
The builtin and
/usr/bin/falsebehave the same everywhere. GNU's executable accepts--helpand--versionand still exits with status 1 afterwards.
Related
trueDo nothing and exit with status 0 (success).testEvaluate a condition about files, strings or integers and return 0 for true or 1 for false.setTurn shell options such as -e, -u, -x and pipefail on or off, and replace the positional parameters.trapRun a command when the shell receives a signal or exits, typically to clean up temporary files.- Exit codesWhat exit statuses mean, how $? works, the reserved values 126, 127 and 128+N, PIPESTATUS, and how to choose codes for your own scripts.
- Strict mode and its caveatsWhat set -euo pipefail actually does, the cases where -e silently does nothing, the traps in -u and pipefail, and a balanced way to use it.
- ConditionalsHow if, elif, &&, || and ! decide using exit statuses, the three test syntaxes, guard clauses, and why `a && b || c` is not an if-else.