表达式
( expression )- 返回表达式的值。
- 改变运算优先级:
expr1 && (expr2 || expr3)
! expressionexpression1 && expression2, expression1 == false, expression2不执行expression1 || expression2, expression1 == true, expression2不执行
条件表达式: CONDITIONAL EXPRESSIONS
使用 [[ 复合命令, test, [ 内置命令 来测试文件属性, 执行字符串和算术比较。
test, [命令根据参数的数量确定它们的行为。- 表达式中使用文件:如果系统提供特殊文件则直接使用。否则,如果其中一个主文件的任何文件参数的格式为 /dev/fd/n,则检查文件描述符n。如果主文件之一的文件参数是 /dev/stdin、/dev/stdout、 /dev/stderr 分别检查文件描述符 0、1、2。除非另有说明,否则主文件为符号链接时,在链接的目标上操作,而不是链接本身。
- 当与 [[ 一起使用时,< 和 > 运算符使用当前语言环境按字典顺序排序。
表达式由以下一元或二元基元组成:
| expression file | 为真 | true if |
|---|---|---|
| -t fd | 文件描述符 fd 已打开并指向终端 | True if file descriptor fd is open and refers to a terminal. |
| -a file | 文件存在 | True if file exists. |
| -e file | 文件存在 | True if file exists and is a block special file. |
| -b file | 块特殊文件 | True if file exists and is a character special file. |
| -c file | 字符特殊文件 | True if file exists and is a directory. |
| -d file | 目录类型 | True if file exists. |
| -f file | 常规文件 | True if file exists and is a regular file. |
| -g file | set-group-id. | True if file exists and is set-group-id. |
| -h file | 符号链接 | True if file exists and is a symbolic link. |
| -L file | 符号链接 | True if file exists and is a symbolic link. |
| -k file | 设置了 sticky 位 |
True if file exists and its sticky bit is set. |
| -p file | 命名管道(FIFO) | True if file exists and is a named pipe (FIFO). |
| -r file | 可读 | True if file exists and is readable. |
| -w file | 可写 | True if file exists and is writable. |
| -x file | 可执行 | True if file exists and is executable. |
| -s file | 大小 > 0 | True if file exists and has a size greater than zero. |
| -u file | set-user-id 位被设置 |
True if file exists and its set-user-id bit is set. |
| -G file | 由有效ground_id拥有 | True if file exists and is owned by the effective group id. |
| -O file | 由有效user_id拥有 | True if file exists and is owned by the effective user id. |
| -N file | 自上次阅读以来已被修改 | True if file exists and has been modified since it was last read. |
| -S file | socket | True if file exists and is a socket. |
| file1 -ef file2 | file1 和 file2 引用自相同的设备和 inode 号 | True if file1 and file2 refer to the same device and inode numbers. |
| file1 -nt file2 | file1 比 file2 新(根据修改日期),或者 file1 存在而 file2 不存在 | True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not. |
| file1 -ot file2 | file1 比 file2 旧,或者 file2 存在而 file1 不存在 | True if file1 is older than file2, or if file2 exists and file1 does not. |
| expression shell_env | 为真 | true if |
|---|---|---|
| -o optname | shell 选项 optname 已启用 | True if the shell option optname is enabled. |
| -v varname | shell 变量 varname 已设置(已被赋值) | True if the shell variable varname is set (has been assigned a value). |
| -R varname | shell 变量 varname 已设置并且是名称引用 | True if the shell variable varname is set and is a name reference. |
| expression string | 为真 | true if |
|---|---|---|
| -z string | 字符串长度 == 0 | True if the length of string is zero. |
| string | 字符串长度 != 0 | True if the length of string is non-zero. |
| -n string | 字符串长度 != 0 | True if the length of string is non-zero. |
| string1 = string2 | True if the strings are equal. | |
| string1 == string2 | [[ 下支持,如果启用shell的nocasematch,忽略大小写 |
True if the strings are equal. |
| string1 != string2 | [[下如果启用shell的nocasematch,忽略大小写 |
True if the strings are not equal. |
| string1 < string2 | [[时使用当前语言环境按字典顺序, 否则ASCII字典序比较 |
True if string1 sorts before string2 lexicographically. |
| string1 > string2 | [[时使用当前语言环境按字典顺序, 否则ASCII字典序比较 |
True if string1 sorts after string2 lexicographically. |
| =~ | [[ 下支持,正则匹配 |
=~, 正则匹配,右侧为模式串。如果模式串语法错误,指令退出状态为2。- 右侧模式串为正则表达式时,不能加引号,否则会作为字符串进行比较
- 并非所有解释器都支持该语法,比如
zsh便不支持。
# 正则模式串不能加引号, 否则会作为字符串进行比较
[[ example.com =~ ^.*.com$ ]] && echo true || echo false # true
[[ example.com =~ "^.*.com$" ]] && echo true || echo false # false
[[ ^.*.com$ =~ "^.*.com$" ]] && echo true || echo false # true
| arg1 OP arg2 | as |
|---|---|
| -eq | == |
| -ne | != |
| -lt | < |
| -le | <= |
| -gt | > |
| -ge | >= |
- arg1, arg2 为整数
- 当在
[[ ]]中, arg1 和 arg2 会做为算术表达式求值。
算数表达式 ARITHMETIC EVALUATION
shell是弱类型,所有的值大多数情况都当作是字符串处理的。比如 a=1;a+=1;echo $a 结果是 11 而不是 2。
要想把内容作为数值进行计算,需要用let, declare, (())。
a=1; let a+=1; echo $a
declare -i a=1; a+=1; echo $a
a=1; ((a+=1)); echo $a
let 和 (())等效。支持的运算类似C语言。按优先级:
val++ val----val ++val+val -val!val ~valval ** n, 幂运算* / %+ -<< >>, 位运算<= >= < >== !=&^|&&||expr?expr:expr= *= /= %= += -= <<= >>= &= ^= |=expr1 , expr2, 逗号
算数表达式,指令退出状态
- 表达式求值,同c:
!0 == true; 0 == false - 表达式作为指令, 退出状态, 根据表达式值确定:
表达式值 == true ? 0 : 1
# let expr
a=1
let a-- # 或((a--))
echo $? # 上一条语句退出状态,0(true)
a=1
let --a # 或 ((--a))
echo $? # 1(false)
- 首先确定表达式范围:
a--和--a a--作为数值处理,整条表达式值为1(true),所以整条let a--作为命令处理,执行结果为 true(0)- 同理
--a, 数值表达式为0(false), 整条命令let --a结果为false(1)