LinuxCommandLibrary

]]

Conditional evaluation within shell scripts

TLDR

View documentation for the [[ keyword

$ tldr [[
copy

SYNOPSIS

[[ expression ]]

PARAMETERS

string1 == string2
    True if string1 matches string2. Uses pattern matching when string2 contains wildcard characters.

string1 != string2
    True if string1 does not match string2.

string1 < string2
    True if string1 sorts before string2 lexicographically.

string1 > string2
    True if string1 sorts after string2 lexicographically.

string1 =~ regex
    True if string1 matches the extended regular expression regex. (Bash only)

-a file
    True if file exists.

-b file
    True if file exists and is a block special file.

-c file
    True if file exists and is a character special file.

-d file
    True if file exists and is a directory.

-e file
    True if file exists.

-f file
    True if file exists and is a regular file.

-g file
    True if file exists and its set-group-id bit is set.

-h file
    True if file exists and is a symbolic link.

-L file
    True if file exists and is a symbolic link.

-n string
    True if the length of string is non-zero.

-o optname
    True if shell option optname is enabled.

-p file
    True if file exists and is a named pipe (FIFO).

-r file
    True if file exists and is readable.

-s file
    True if file exists and has a size greater than zero.

-S file
    True if file exists and is a socket.

-t fd
    True if file descriptor fd is open and refers to a terminal.

-u file
    True if file exists and its set-user-id bit is set.

-v varname
    True if shell variable varname is set (has been assigned a value).

-w file
    True if file exists and is writable.

-x file
    True if file exists and is executable.

-z string
    True if the length of string is zero.

DESCRIPTION

The `[[ ... ]]` construct is a feature in shells like Bash, Ksh, and Zsh that provides a more robust and feature-rich way to perform conditional tests compared to the traditional `[ ... ]` command. It allows for advanced string matching, regular expression matching, arithmetic comparisons, and file attribute checks. Crucially, `[[ ... ]]` avoids word splitting and pathname expansion, making it safer and more predictable when dealing with variables containing spaces or wildcards. It's often used in `if` statements to control the flow of shell scripts. It's not a command itself but part of the shell syntax.

CAVEATS

The `[[ ... ]]` construct is not available in all shells, particularly older shells like Bourne shell (`sh`). It's specific to more modern shells like Bash, Ksh, and Zsh. Also, be aware that single quotes prevent variable expansion, so tests involving variables will not work as expected if enclosed in single quotes.

WORD SPLITTING AND GLOBBING

Unlike `[ ... ]`, `[[ ... ]]` prevents word splitting and filename generation (globbing).
This means you don't need to quote variables that might contain spaces or wildcards.
For example, `[[ $var == * ]]` will work as expected even if `$var` contains spaces.

REGULAR EXPRESSIONS

The `=~` operator allows you to use regular expressions within `[[ ... ]]` in Bash.
This provides much more sophisticated string matching capabilities compared to simple wildcard matching.

LOGICAL OPERATORS

`[[ ... ]]` uses `&&` and `||` for logical AND and OR, respectively, which are more natural and less prone to errors compared to `-a` and `-o` used with `[ ... ]`.
Parentheses can be used for grouping: `[[ ( condition1 && condition2 ) || condition3 ]]`.

HISTORY

The `[[ ... ]]` construct was introduced to provide more reliable and powerful conditional testing in shells. It addresses shortcomings of the older `test` command (also represented by `[ ... ]`), such as the need to quote variables to prevent word splitting and pathname expansion. Ksh was one of the first shells to implement `[[ ... ]]`, and it was later adopted by Bash and Zsh. Its usage has grown significantly due to its safety and expressiveness.

SEE ALSO

test(1), [(1)

Copied to clipboard