Syntax test expr [ expr ] [[ expr ]]
[ is a synonym for test but requires a final argument of ].
The double bracket [[ construct, also known as 'extended test' or 'New Test' is more versatile, the old test [ is more portable.
In most cases, on modern systems, you should prefer the use of new test [[
If one side of the expression expr evaluates to nothing (Null) then [ will throw an error, [[ will handle this automatically.
Spaces around the brackets are important - each operator and operand must be a separate argument.
To do a simple numeric comparison (or any other shell arithmetic), use (( )) instead of test:
To test variables you should quote the "variablename" as they may undergo word splitting or globbing, with New test [[ this is not necessary
[ "$DEMO" = 5 ]
[[ $DEMO == 10 ]]
Multiple Expressions can be combined using the following operators, listed in decreasing order of precedence.
! expr True if expr is false. ( expr ) Returns the value of expr. This can be used to override the normal precedence of operators. expr1 && expr2 True if both expr1 and expr2 are true.
expr1 || expr2 True if either expr1 or expr2 is true.
The old test [ can also use the -a and -o operators, and ( ... ) grouping, as defined by POSIX but only for strictly limited cases, and these are now marked as deprecated.
The test
and [
builtins evaluate
conditional expressions using a set of rules based on the number of arguments.
0 arguments The expression is false. 1 argument The expression is true if and only if the argument is not null. 2 arguments If the first argument is '!', the expression is true if and only if the second argument is null. If the first argument is one of the unary conditional operators, the expression is true if the unary test is true. If the first argument is not a valid unary operator, the expression is false. 3 arguments If the second argument is one of the binary conditional operators, the result of the expression is the result of the binary test using the first and third arguments as operands. If the first argument is '!', the value is the negation of the two-argument test using the second and third arguments. If the first argument is exactly '(' and the third argument is exactly ')', the result is the one-argument test of the second argument. Otherwise, the expression is false. The '-a' and '-o' operators are considered binary operators in this case. 4 arguments If the first argument is '!', the result is the negation of the three-argument expression composed of the remaining arguments. Otherwise, the expression is parsed and evaluated according to precedence using the rules listed above. 5 or more arguments The expression is parsed and evaluated according to precedence using the rules listed above.
These options test for particular types of files. All cases will only return True (0) if the file exists.
-b file True if file exists and is a Block special device. [[ -b demofile ]] -c file True if file exists and is a Character special device. [[ -c demofile ]] -d file True if file exists and is a Directory. [[ -d demofile ]] -e file True if file Exists. [[ -e demofile ]] -f file True if file exists and is a regular File. [[ -f demofile ]] -g file True if file exists and its set-group-id bit set. [[ -g demofile ]] -G file True if file exists and is owned by the current effective group id. [[ -G demofile ]] -k file True if file exists and has its "sticky" bit set. [[ -k demofile ]] -h file True if file exists and is a symbolic Link. [[ -h demofile ]] -L file True if file exists and is a symbolic Link. [[ -L demofile ]] -n string True if the length of string is nonzero. -O file True if file exists and is owned by the current effective user id. [[ -O demofile ]] -p file True if file is a named Pipe (FIFO). [[ -p demofile ]] -r file True if file exists and is readable. [[ -r demofile ]] -s file True if file has a Size greater than zero. [[ -s demofile ]] -S file True if file exists and is a Socket. [[ -S demofile ]] -t [file_descriptor] True if file_descriptor is opened on a terminal. If file_descriptor is omitted, it defaults to 1 (standard output). [[ -t demofile ]] -u file True if file has its set-user-id bit set. [[ -L demofile ]] -w file True if file exists and is writable. [[ -w demofile ]] -x file True if file exists and is executable. [[ -x demofile ]] file1 -ef file2 True if file1 and file2 have the same device and inode numbers, i.e. they are hard links to each other.
file1 -nt file2 True if file1 exists and is newer than file2. [[ demofile1 -nt $DEMO ]] file1 -ot file2 True if file1 exists and is older than file2. [[ $DEMO -ot demofile2 ]] file1 -ef file2 True if file1 and file2 exist and refer to the same file.
Comparison strings for test do not need to be quoted, though you can quote them to protect characters with special meaning to the shell, e.g. spaces.
Comparisons using New test [[ perform pattern matching against the string on the right hand side unless you quote the "string" on the right. This prevents any characters with special meaning in pattern matching from taking effect.
-z String True if the length of String is zero. -n String True if the length of String is nonzero. String True if the length of String is nonzero. String1 = String2 True if the strings are equal. [[ String1 = "String2" ]] True if the strings are equal (Literal, no pattern match). String1 != String2 True if the strings are not equal. [[ a != b ]] && echo "a is not equal to b" [[ a > b ]] || echo "a does not come after b" [[ az < za ]] && echo "az comes before za" [[ a = a ]] && echo "a equals a" As of bash 4.1 (2010), string comparisons made with [[ and using < or > will respect the current locale. Wildcard matching with [[ [[ $NAME = demo* ]] || echo "NAME does not start with 'demo': $name"
-o OPTION True if the shell option OPTION is enabled.-v VAR True if the shell variable VAR is set.-R VAR True if the shell variable VAR is set and is a name reference.! EXPR True if expr is false.EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.
These are normally used in conjunction with another non-math test operator somewhere in the expression.
For a purely numeric comparison, it is better to use (( )) instead of test or New test [[The arguments must be entirely numeric (possibly negative), or the special expression -l STRING which evaluates to the length of STRING. The < and > operators can also be used with new test [[
ARG1 -eq ARG2 Returns true if ARG1 is equal to ARG2 [[ 5 -eq 05 ]] && echo "5 equals 05" ARG1 -ne ARG2 Returns true if ARG1 is not-equal to ARG2 [[ 6 -ne 20 ]] && echo "6 is not equal to 20" ARG1 -lt ARG2 Returns true if ARG1 is less-than to ARG2 [[ 8 -lt 9 ]] && echo "8 is less than 9" [[ 3 < 4 ]] && echo "3 is less than 4" ARG1 -le ARG2 Returns true if ARG1 is less-than-or-equal to ARG2 [[ 3 -le 8 ]] && echo "3 is less than or equal to 8" ARG1 -gt ARG2 Returns true if ARG1 is greater-than to ARG2 [[ 5 -gt 10 ]] || echo "5 is not bigger than 10" [[ 4 > 2 ]] && echo "4 is greater than 2" ARG1 -ge ARG2 Returns true if ARG1 is greater-than-or-equal to ARG2 [[ 3 -ge 3 ]] && echo "3 is greater than or equal to 3"If file is a symbolic link, test will fully dereference it and then evaluate the expression against the file referenced, except for the -h and -L primaries.
These primaries can be combined with the following operators:
! expression True if expression is false. expression1 -a expression2 True if both expression1 and expression2 are true. expression1 -o expression2 True if either expression1 or expression2 are true. ( expression ) True if expression is true.Some shells may provide a builtin test command which is similar or identical to this utility. Consult the builtin(1) manual page.
The test utility exits with one of the following values:
0 expression evaluated to true.
1 expression evaluated to false or expression was missing.
>1 An error occurred.
test -1 -gt -2 && echo yes # yes test -l abc -gt 1 && echo yes # yes test 0x100 -eq 1 # error--> test: integer expression expected before -eq
Test if the non existent file paris.txt is readable, the value returned is false (non zero)
test -r paris.txt echo $? # 1
Test if the file amsterdam.txt exists:
If [[ -e amsterdam.txt ]]; then echo "we found the file" fi
Test the associative array a to see if it contains an entry indexed by the expansion of i
test -v a['$i']
Test the logged in username, if the logname variable = scott then the test returns TRUE (0):
if [[ "$LOGNAME" = "scott" ]]; then
echo "Logged in as Scott"
else
echo "incorrect user"
fi
The double bracket [[ construct is a “compound command” while test and the single bracket [ are shell built-ins.
"The test of a vocation is the love of the drudgery it involves" ~ Logan Pearsall
Examples of test constructs - Advanced Bash-Scripting Guide.
How-to: Use parentheses to group and expand expressions
case - Conditionally perform a command.
cmp - Compare two files.
expr - Evaluate expressions.
eval - Evaluate several commands/arguments.
for - Expand words, and execute commands.
if - Conditionally perform a command.
pathchk - Check file name portability.
Equivalent Windows command: IF - Conditionally perform a command.