if
Conditionally execute commands based on a test
TLDR
Execute the specified commands if the condition command's exit status is zero
Execute the specified commands if the condition command's exit status is not zero
Execute the first specified commands if the condition command's exit status is zero otherwise execute the second specified commands
Check whether a [f]ile exists
Check whether a [d]irectory exists
Check whether a file or directory [e]xists
Check whether a variable is defined
List all possible conditions (test is an alias to [; both are commonly used with if)
SYNOPSIS
if test-commands; then consequent-commands;
[elif more-test-commands; then more-consequents;]
[else alternate-commands;] fi
PARAMETERS
test-commands
Commands evaluated for condition; last one's exit status (0=true) decides branch
then
Keyword starting commands for true condition
elif
Optional keyword for additional test-then pairs
else
Optional keyword for commands if all prior conditions false
fi
Required keyword ending the if block
DESCRIPTION
The if statement is a core control flow construct in Unix shells like Bash and POSIX sh, enabling conditional execution of commands based on the exit status of preceding tests.
It begins with if followed by a list of test-commands separated by semicolons. The shell executes these commands, and if the final command exits with status zero (success), it runs the commands after then. Optional elif clauses provide chained conditions, else handles fallback, and fi terminates the block.
Tests typically use builtins like test (or [), [[ in Bash for string/file/arithmetic checks, or any command's exit code. Only the last test-command's status matters; short-circuiting occurs with && or ||.
Essential for scripting logic: file checks, user input validation, error handling. Supports nesting for complex flows. Readability improves with indentation, though not required. Portable across shells.
CAVEATS
Condition relies only on final test-command's exit status, not output.
Requires proper semicolon before then/elif/else.
No implicit boolean conversion; use test or arithmetic for comparisons.
Nesting needs matching fis.
SIMPLE EXAMPLE
if [ -f /etc/passwd ]; then
echo File exists;
fi
WITH ELIF/ELSE
if [ "$1" = start ]; then
service foo start;
elif [ "$1" = stop ]; then
service foo stop;
else
echo Usage: $0 {start|stop};
fi
HISTORY
Originated in Bourne shell (1977, Bell Labs). Standardized in POSIX.1-1988. Bash/Zsh extend with [[ for advanced tests.


