Home / Alt manpages / false(1)

  • false(1)
  • User command
  • linux

Use false to Test Failure Paths in Shell Scripts

You will use false to make a shell command return failure on demand, then verify how that status changes an if branch, an || fallback, and a pipeline. The command does not change files, print normal output, or need elevated privileges. Allow about ten minutes for the examples and a little longer if you are testing a real script.

You need a POSIX-like shell such as Bash or Dash. The installed external command used for the version checks below is GNU coreutils 9.4, from Ubuntu package coreutils 9.4-3ubuntu6.3. Your shell normally provides its own false builtin, which usually takes precedence over /usr/bin/false. That distinction matters when you ask for help or version information.

1. Confirm which false your shell will run

Start with a read-only lookup:

$ type -a false
false is a shell builtin
false is /usr/bin/false
false is /bin/false

The exact paths can differ. The first entry is the command used by an ordinary false invocation in Bash. Use the external path explicitly when you need the GNU program documented by the installed manpage:

$ command -v false
false

That output identifies the shell name rather than proving that an external file is being used. Treat type -a as the useful checkpoint.

2. Observe the failure status

Run false on its own, then immediately inspect the special parameter $?:

$ false
$ printf 'exit status: %s\n' "$?"
exit status: 1

There is normally no output from false. Status 1 is a conventional failure status, not a shell error and not a signal termination. Any command run afterwards replaces $?, so save or print it before running another diagnostic command.

The GNU program accepts ignored command-line arguments, so this is still a deliberate failure:

$ /usr/bin/false ignored arguments
$ printf 'external status: %s\n' "$?"
external status: 1

Neither form needs sudo. The command's purpose is its exit status; it does not create, delete, or alter anything.

3. Put false in an if statement

Shell conditionals test the exit status of a command. A zero status selects the success branch, while a non-zero status selects else:

$ if false; then
>     printf 'success branch\n'
> else
>     printf 'failure branch\n'
> fi
failure branch

This is useful for exercising an error path without first making a real command fail. Replace false with the command or function whose failure handling you need to test once the branch itself is understood.

Checkpoint: the result is correct when only failure branch appears and the compound command finishes with status zero, because the final printf succeeded:

$ if false; then :; else printf 'handled\n'; fi
handled
$ printf 'status after handling: %s\n' "$?"
status after handling: 0

4. Test an alternative with ||

The || operator runs its right-hand command only when the left-hand command fails. This makes false a compact test double for a failed check:

$ false || printf 'fallback ran\n'
fallback ran
$ true || printf 'this is not printed\n'

The status of the whole list is the status of the command that ran last. In the first example, printf succeeds, so the list returns zero. If the fallback must itself fail, make that explicit and inspect it:

$ false || false
$ printf 'list status: %s\n' "$?"
list status: 1

A common distraction is to read || as a request to print an error. It is control flow, not logging. Add a message or diagnostic command when a human needs to see what happened.

5. Check pipeline status before relying on it

In a basic shell pipeline, the status is normally the status of the last command. Therefore this can hide the deliberate failure:

$ false | cat
$ printf 'pipeline status: %s\n' "$?"
pipeline status: 0

Bash provides pipefail to make a pipeline fail when a component fails:

$ set -o pipefail
$ false | cat
$ printf 'pipeline status with pipefail: %s\n' "$?"
pipeline status with pipefail: 1

set -o pipefail changes the current shell for the rest of that shell session. In a temporary interactive test, undo it with:

$ set +o pipefail

Do not assume another shell supports this Bash option. If a script needs pipeline failure detection, declare the shell in its shebang and test the script with that shell.

6. Avoid the set -e test trap

set -e, also called errexit, can stop a script after an unhandled non-zero status. A bare false is therefore a poor test fixture inside a script that has enabled it:

$ bash -c 'set -e; false; printf "unreachable\n"'
$ printf 'script status: %s\n' "$?"
script status: 1

Use a conditional context when the failure is expected. The shell does not treat the test command in this if as an unhandled failure:

$ bash -c 'set -e; if false; then :; else printf "expected failure handled\n"; fi'
expected failure handled

This does not make set -e a complete error policy. Its exceptions around conditionals, lists, and pipelines are easy to misread. For important scripts, handle expected failures explicitly and check the status you actually intend to accept.

7. Use GNU help and version output deliberately

The external GNU command recognises --help and --version, but still exits with status 1 because it remains the false command:

$ /usr/bin/false --version
false (GNU coreutils) 9.4
...
$ printf 'status: %s\n' "$?"
status: 1

The shell builtin can produce no help or version text for these arguments and still return 1. Use the explicit path when documenting or checking GNU-specific behaviour. Do not use a version probe as a success test: read its output and expect its failure status.

Done means

  • You confirmed whether the shell resolves false to a builtin, an external command, or both.
  • You verified that false returns status 1 and produces no normal output.
  • You exercised a failure branch with if or a fallback with ||.
  • You know that a pipeline can hide an earlier failure unless the shell supports and enables pipefail.
  • You kept expected failures inside explicit handling when set -e is active.