test

Condition evaluation.
Evaluate an expression and, if it evaluates to true, return a zero (true) exit status; otherwise return 1 (false). If there is no expression, test also returns 1 (false).

      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.

File type tests

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.

File Age Tests (modification date)

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.

String tests

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"

Other operators:

-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.

Numeric tests

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.

Exit Status

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.

Examples

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

Related macOS commands

eval - Evaluate several commands/arguments.
expr - Evaluate expressions.


 
Copyright © 1999-2024 SS64.com
Some rights reserved