test operators

最後更新: 2020-08-19

前言

Bash variables are not strongly typed

目錄

 


Test CLI

 

An omitted EXPRESSION defaults to false.  
Otherwise, EXPRESSION is true or false and sets exit status.

test; echo $?

1

test 1234; echo $?

0

test /bin/false; echo $?

0

test -z 1234; echo $?       # "-z" the length of STRING is zero

1

 


常用

 

"!" => 取反

存在

-e FILE             FILE 是否存在, 不論它是什麼來.
-d FILE             FILE exists and is a directory
-f FILE             FILE exists and is a regular file
-s FILE             FILE exists and has a size greater than zero
-L FILE             returns true if the "file" exists and is a symbolic link

-b FILE             FILE exists and is block special (i.e. sda)
-c FILE             FILE exists and is character special
-L FILE             FILE exists and is a symbolic link (same as -h)
-p FILE             FILE exists and is a named pipe
-S FILE             FILE exists and is a socket

Permission & owner

-r FILE             FILE exists and read permission is granted
-x FILE             FILE exists and execute (or search) permission is granted
-w FILE             FILE exists and write permission is granted

-u FILE             FILE exists and its set-user-ID bit is set
-g FILE             FILE exists and is set-group-ID
-k FILE             FILE exists and has its sticky bit set

 


"[]"

 

[ aka test

Example:

[ -f /etc/hosts ] && echo "Found" || echo "Not found"

[ ! -f /etc/hosts ] && echo "Not found" || echo "Found"

       1a    2a    3a    4a    5a    6a    |1b    2b    3b    4b    5b    6b
       [     ["    [-n   [-n"  [-z   [-z"  |[[    [["   [[-n  [[-n" [[-z  [[-z"
unset: false false true  false true  true  |false false false false true  true
null : false false true  false true  true  |false false false false true  true
space: false true  true  true  true  false |true  true  true  true  false false
zero : true  true  true  true  false false |true  true  true  true  false false
digit: true  true  true  true  false false |true  true  true  true  false false
char : true  true  true  true  false false |true  true  true  true  false false
hyphn: true  true  true  true  false false |true  true  true  true  false false

Both true and false are valid shell commands that do nothing but return an error code of 0 and 1

if false; then
  ..
fi

 * "test"("[]") doesn't use the strings true and false for boolean values.

 * test treats any non-empty string as true, and an empty string as false.

 * [ ! $state ] will always revert to the logical false

 


[[ ]] 與 []

 

"[]" 

  • synonym for test (/usr/bin/test)
  • a builtin in bash for efficiency reasons

"[[]]"

1. It is a bash extension

2. The double bracket [[ ... ]] extended 'test' construct

3. Its regex matching ("=~")

answer=Yesss
if [[ $answer =~ ^Yes ]]; then

4. prevents word splitting of variable values (if VAR="var with spaces")

if [[ -f $file_has_space ]]

5. it do pattern globbing matching on strings when the = or != operators without ""

[[ $a == z* ]]   # True if $a starts with an "z" (pattern matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

[ $a == z* ]     # File globbing and word splitting take place.
[ "$a" == "z*" ] # True if $a is equal to z* (literal matching).

注意:

  • 比較符號 "[", "]" 兩邊一定要有空格 !!

 


Logic Test

 

要比較的東西兩邊都要有空格 !!

錯誤例子:

[ "$a" =="$b" ]
#       /\
#    這裡必須要有空格

String compare(ASCII comparison):

== / =    # "=" 是用來做比較的, 沒有指派功能 !!
!=
-z        # null
-n        # non-null

Arithmetic comparison:

-eq
-ne
-gt
-ge
-lt
-le

數學符號只能在 (( )) 內使用

>
>=
<
<=

(()) 是 arithmetic expression (evaluation) and sets the exit status to 1 if the expression evaluates to 0

[] 用時, < and > operators are also used by the shell for redirection, 所以要用 \< or \>

i.e.

>

if (("$a" > "$b")); then

-gt

if [ "$a" -gt "$b" ]; then

null 的常見錯誤:

我們可以用 "-n" 及 "-z" 去 detect null

# -n non-zero length string

if [ -n $string ]; then
  echo "String \"string\" is not null."              # 明明 $string 沒有set, 結果竟然是這個
else  
  echo "String \"string\" is null."
fi

原因係 $string 沒有用 "" 去拘起 !!

if [ -z "$string" ]; then
  echo "String \"string\" is null."
else
  echo "String \"string\" is not null."
fi

 

AND 與 OR

&&, -a     # and
||, -o     # or

i.e.

  • if [ $r -eq 0 -o $r -eq 32 ]; then
  • if [ $r -eq 0 ] || [ $r -eq 32 ]; then
  • if [[ $r -eq 0 || $r -eq 32 ]]; then

P.S.

處理比較要小心, 最好用這樣的格式 "x$string"

 


注意

# Result: 0 is true.

echo "Testing \"0\""
if [ 0 ]      # zero
then
  echo "0 is true."
else          # Or else ...
  echo "0 is false."
fi            # 0 is true.

因為 if/then construct tests whether the exit status

# Result: False

#!/bin/bash

if [ abc.txt = abc.* ]; then
        echo "True"
else
        echo "False"
fi

 

# Result: True

#!/bin/bash

if [[ abc.txt = abc.* ]]; then
        echo "True"
else
        echo "False"
fi

 


Example

 

Script run with root / user

# root

if [ "$EUID" -eq 0 ]; then
        echo "INFO: The scripts can't run by root"
        exit 1
fi

# user

if [ x`id -un` != x$RunAs ]; then
        echo "INFO: The scripts must run by user: $RunAs"
        exit 1
fi

 

Creative Commons license icon Creative Commons license icon