最後更新: 2020-08-19
前言
Bash variables are not strongly typed
目錄
- Test CLI
- ...
- Example
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