变量
变量的使用
在SHELL中,变量不需要提前声明就可以直接使用,通常变量是以字符串的形式保存的,即使其值是数字类型的情况下也是如此。在Shell环境中变量的命名通常是字母或下划线,其长度并无限制,但是为了兼容性,建议不要超过255个字符,由于Linux系统是大小写敏感的,因此Shell脚本中变量也是大小写敏感的。比如下面的代码中就定义了两个变量,需要注意的是赋值号两端不能有空格,如果等号后边的字符串有空格的话,可以使用单引号或者双引号的方式创建。
CUSTOMER_NAME=张三AGE=43ADDRESS=' China Anhui'
- 使用的变量的时候可以通过$符号+变量名的方式来引用,如:
name=张三age=18echo "Your name is $name"name2=$name,$ageecho "Name2 is $name2"
在Shell中,单引号通常会忽略所有的特殊字符串,而双引号则不会,至于反引号 ‘`’ 其则可以引用系统命令,比如
name=张三echo "$name" # 输出 张三echo '$name' # 输出 $nameecho `pwd` # 输出当前的工作目录
变量的类型
在Shell中变量主要有四种类型,分别是
- 用户自定义变量: 在shell脚本中定义的变量,只在shell脚本中生效,一般使用小写字母表示
- 环境变量: 当shell脚本执行的时候,会从系统中读取变量,这些预置的变量称之为环境变量,通常环境变量会在配置文件目录 (/etc/profile) 文件中配置,用户可以使用export 命令在系统中创建环境变量
- 位置变量: 位置变量值得是 $0/$1/$2 这些运算符表示传入Shell脚本中的参数等等
- 预定义变量: 表示在Shell中已经定义好的变量,比如
!表示最后一个线程的PID号
运算
Shell中的运算和C语言差不多,优先级以及顺序也是一样,前面提到shell中所有的变量都是字符串保存的,因此在进行计算的时候需要特殊的手段转换类型。
使用expr 命令记性算数表达式求值
#!/bin/bashn1=2n2=3n3=`expr $n1 + $n2`echo "value = $n3"
expr 支持的逻辑运算如下,但是使用expr表达式需要使用\进行转义,这需要特别注意
| 表达式 | 说明 |
|---|---|
| expr1 | expr2 |
| expr1 & expr2 | 逻辑运算 与 |
| expr1 = expr2 | 逻辑运算 等于 等价于 == |
n1=5;n2=6;n3=0echo $(expr $n1 | $n3) # 输出 5echo $(expr $n2 & $n3) # 输出 0echo $(expr $n1 & $n2) # 输出 5echo $(expr $n1 <= $n2) # 输出 1echo $(expr $n1 * $n2) # 输出 30echo $(expr $n1 = 2) # 输出 1
使用$((…)) 表达式求值
expr表达式需要转义字符的支持,这比较麻烦,通常采用$((..))的方式计算
#!/bin/bashn3=3;n4=4;echo $(($n3 + $n4)) # 输出 7。echo $((n3 + n4)) # 输出 7 。可见,变量前不加 $ 也是可以的echo $(($n3 | $n4)) # 输出 7 。这里的 | 是按位或操作符echo $(($n3 || $n4)) # 输出 1 。这里的 || 是逻辑或操作符echo $(($n3 & $n4)) # 输出 0 。这里的 & 是按位与操作符echo $(($n3 && $n4)) # 输出 1 。这里的 && 是逻辑与操作符echo $(($n3 * $n4)) # 输出 12echo $(($n3 == $n4)) # 输出 0 exit 0
流程控制
判断
使用if语法可以进行流程控制,其语法格式如下
# 如果表达式成立则执行代码if test 表达式; then#...fi# 或者使用其简写的方式if [ 表达式 ]; then#...fi# if...else...if [ 表达式 ]; then#...else#...fi# if...elif..elseif [ 表达式 ]; then#...elif [ 表达式 ]; then#...else#...fi
使用test命令可以判断表示式是否城里等,其常见的操作如下
| 表达式 | 结果 |
|---|---|
| string1 = string2 | 如果两个字符串相同则结果为真 |
| string1 != string2 | 如果两个字符串不同则结果为真 |
| -n string | 如果字符串不为空则结果为真 |
| -z string | 如果字符串为空(null),则结果为真 |
| expr1 -eq expr2 | 如果两个表达式相等,则结果为真 |
| expr1 -ne expr2 | 如果两个表达式不相等,则结果为真 |
| expr1 -gt expr2 | 如果 expr1 > expr2 ,则结果为真 |
| expr1 -ge expr2 | 如果 expr1 >= expr2 ,则结果为真 |
| expr1 -lt expr2 | 如果 expr1 < expr2,则结果为真 |
| expr1 -le expr2 | 如果 expr1 <= expr2,则结果为真 |
| !expr | 如果表达式为假,则结果为真 |
| -d file | 如果文件是一个目录,则结果为真 |
| -e file | 如果文件存在,则结果为真。注意,历史上 -e 选项不可移植,所以通常使用的是 -f 选项 |
| -f file | 如果文件存在且为普通文件,则结果为真 |
| -g file | 如果文件的 set-group-id 位被设置,则结果为真 |
| -r file | 如果文件可读,则结果为真 |
| -s file | 如果文件大小不为 0 ,则结果为真 |
| -u file | 如果文件的 set-user-id 为被设置,则结果为真 |
| -w file | 如果文件可写,则结果为真 |
| -x file | 如果文件可执行,则结果为真 |
下面的代码示例将展示部分语法的使用方式
# 字符串比较str1="zhangsan"str2="lisi"# 如果条件成立,字符串相等if test "$str1" = "$str2" ; thenecho "字符串相等"fi# 也可以使用[] 代替 test 这是常见的写法if [ "$str1" != "$str2" ] ; thenecho "字符串不相等"fiif [ -n "$str1" ] ; thenecho "字符串不为空"fi# 数字比较n1=1n2=2if [ "$n1" -eq "$n2" ] ; thenecho "n1 等于 n2"fiif [ "$num1" -le "$num2" ] ; thenecho "n1 小于 n2"fi# 文件比较判断# 如果文件存在且为普通文件if [ -f /bin/bash ] ; thenecho "file /bin/bash exists"fi# 如果是一个目录if [ -d /bin/bash ] ; thenecho "/bin/bash is a directory"elseecho "/bin/bash is not a directory"fi
循环
- for循环语句
shell 中的 for 语句与 C 语言等的 for 语句格式不一样,但都是用来循环处理一组值的。这组值可以是任意字符串的集合(shell 在默认情况下所有变量都是以字符串的形式存储的),它们可以在程序里被列出,更常见的做法是使用 shell 的文件名扩展结果。 for 循环将会重复整个对象列表,依次执行每一个独立对象的循环内容。对象可能是命令行参数、文件名或是任何可以以列表形式建立的东西。
其语法如下:
for variable in valuesdostatementsdone
for 命令可以执行指定次数的一个或多个命令。在执行循环时,参数列表 values(可以有多个参数,如val1、val2、val3、…) 中的第一个参数将被赋给变量 variable,然后执行循环体(do 与 done 之间的命令);然后将列表中的第二个参数赋给 variable,依次循环,直到列表中的参数用完。
举个简单的例子:
for name in can you speak Englishdoecho $namedone
这段代码将依次打印参数列表中的参数。 关于 for 语句,还有许多其他细节,读者有兴趣可以自行了解。
回到顶部
- while 与 until 语句
如果你需要进行循环操作而是先不知道需要循环的次数,可以使用 while 循环,while 循环的语法如下:
while conditiondostatementsdone
until 循环语句的功能与 while 一样,不同的是对于条件判断结果的处理上。until 循环的语法如下:
until conditiondostatementsdone
在 while 和 until 语句中,condition 是判断条件,不同的是,while 语句中,若判断条件为真,则执行循环体;until 语句中,若判断条件为真,则停止执行循环体。
i=1while [ "$i" -le 10 ]doread -p "请输入一个数字:" idoneecho "$i"
这段代码从键盘中输入一个数字,直到输入数值大于 10,退出循环并打印最后输入的那个值。
分支
与其他编程语言中的 case 语句类似, shell 中的 case 语句也可以用来进行模式匹配,语法如下:
case var inpattern [ | pattern ] ... ) statements1;;pattern [ | pattern ] ... ) statements2;;...esac
关于 case 的语法,有以下几点需要注意:
- case 语句以 case 作为开头,以 esac 作为结尾;
- case 语句的每个模式行都是以双分号 ;; 结尾的;
- 一个模式行可以合并匹配多个模式,使用 | 符作为分隔;
- 一个模式行可以执行多条语句,各语句之间可以使用单分号 ; 隔开,这也是为什么每行的结尾要使用双分号 ;; 作为结束标志的原因;
- case 语句支持使用正则表达式作为匹配项,这使得 case 语句的功能更为强大。
```shell
判断这个字符是字母还是数字,都不是的话返回
case $char in [a-z] | [A-Z] ) echo “字符是一个字母”;; [1-9] ) echo “字符是一个数字”;;
- ) echo “未知类型的字符” esac ```
