变量

变量的使用

在SHELL中,变量不需要提前声明就可以直接使用,通常变量是以字符串的形式保存的,即使其值是数字类型的情况下也是如此。在Shell环境中变量的命名通常是字母或下划线,其长度并无限制,但是为了兼容性,建议不要超过255个字符,由于Linux系统是大小写敏感的,因此Shell脚本中变量也是大小写敏感的。比如下面的代码中就定义了两个变量,需要注意的是赋值号两端不能有空格,如果等号后边的字符串有空格的话,可以使用单引号或者双引号的方式创建。

  1. CUSTOMER_NAME=张三
  2. AGE=43
  3. ADDRESS=' China Anhui'
  • 使用的变量的时候可以通过$符号+变量名的方式来引用,如:
    1. name=张三
    2. age=18
    3. echo "Your name is $name"
    4. name2=$name,$age
    5. echo "Name2 is $name2"

    在Shell中,单引号通常会忽略所有的特殊字符串,而双引号则不会,至于反引号 ‘`’ 其则可以引用系统命令,比如

  1. name=张三
  2. echo "$name" # 输出 张三
  3. echo '$name' # 输出 $name
  4. echo `pwd` # 输出当前的工作目录

变量的类型

在Shell中变量主要有四种类型,分别是

  1. 用户自定义变量: 在shell脚本中定义的变量,只在shell脚本中生效,一般使用小写字母表示
  2. 环境变量: 当shell脚本执行的时候,会从系统中读取变量,这些预置的变量称之为环境变量,通常环境变量会在配置文件目录 (/etc/profile) 文件中配置,用户可以使用export 命令在系统中创建环境变量
  3. 位置变量: 位置变量值得是 $0/$1/$2 这些运算符表示传入Shell脚本中的参数等等
  4. 预定义变量: 表示在Shell中已经定义好的变量,比如Shell 脚本基础语法 - 图1!表示最后一个线程的PID号

运算

Shell中的运算和C语言差不多,优先级以及顺序也是一样,前面提到shell中所有的变量都是字符串保存的,因此在进行计算的时候需要特殊的手段转换类型。

使用expr 命令记性算数表达式求值

  1. #!/bin/bash
  2. n1=2
  3. n2=3
  4. n3=`expr $n1 + $n2`
  5. echo "value = $n3"

expr 支持的逻辑运算如下,但是使用expr表达式需要使用\进行转义,这需要特别注意

表达式 说明
expr1 expr2
expr1 & expr2 逻辑运算 与
expr1 = expr2 逻辑运算 等于 等价于 ==
  1. n1=5;n2=6;n3=0
  2. echo $(expr $n1 | $n3) # 输出 5
  3. echo $(expr $n2 & $n3) # 输出 0
  4. echo $(expr $n1 & $n2) # 输出 5
  5. echo $(expr $n1 <= $n2) # 输出 1
  6. echo $(expr $n1 * $n2) # 输出 30
  7. echo $(expr $n1 = 2) # 输出 1

使用$((…)) 表达式求值

expr表达式需要转义字符的支持,这比较麻烦,通常采用$((..))的方式计算

  1. #!/bin/bash
  2. n3=3;
  3. n4=4;
  4. echo $(($n3 + $n4))       # 输出 7。
  5. echo $((n3 + n4)) # 输出 7 。可见,变量前不加 $ 也是可以的
  6. echo $(($n3 | $n4)) # 输出 7 。这里的 | 是按位或操作符
  7. echo $(($n3 || $n4)) # 输出 1 。这里的 || 是逻辑或操作符
  8. echo $(($n3 & $n4)) # 输出 0 。这里的 & 是按位与操作符
  9. echo $(($n3 && $n4)) # 输出 1 。这里的 && 是逻辑与操作符
  10. echo $(($n3 * $n4)) # 输出 12
  11. echo $(($n3 == $n4)) # 输出 0 exit 0

流程控制

判断

使用if语法可以进行流程控制,其语法格式如下

  1. # 如果表达式成立则执行代码
  2. if test 表达式; then
  3. #...
  4. fi
  5. # 或者使用其简写的方式
  6. if [ 表达式 ]; then
  7. #...
  8. fi
  9. # if...else...
  10. if [ 表达式 ]; then
  11. #...
  12. else
  13. #...
  14. fi
  15. # if...elif..else
  16. if [ 表达式 ]; then
  17. #...
  18. elif [ 表达式 ]; then
  19. #...
  20. else
  21. #...
  22. 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 如果文件可执行,则结果为真

下面的代码示例将展示部分语法的使用方式

  1. # 字符串比较
  2. str1="zhangsan"
  3. str2="lisi"
  4. # 如果条件成立,字符串相等
  5. if test "$str1" = "$str2" ; then
  6. echo "字符串相等"
  7. fi
  8. # 也可以使用[] 代替 test 这是常见的写法
  9. if [ "$str1" != "$str2" ] ; then
  10. echo "字符串不相等"
  11. fi
  12. if [ -n "$str1" ] ; then
  13. echo "字符串不为空"
  14. fi
  15. # 数字比较
  16. n1=1
  17. n2=2
  18. if [ "$n1" -eq "$n2" ] ; then
  19. echo "n1 等于 n2"
  20. fi
  21. if [ "$num1" -le "$num2" ] ; then
  22. echo "n1 小于 n2"
  23. fi
  24. # 文件比较判断
  25. # 如果文件存在且为普通文件
  26. if [ -f /bin/bash ] ; then
  27. echo "file /bin/bash exists"
  28. fi
  29. # 如果是一个目录
  30. if [ -d /bin/bash ] ; then
  31.   echo "/bin/bash is a directory"
  32. else
  33.   echo "/bin/bash is not a directory"
  34. fi

循环

  

  • for循环语句

shell 中的 for 语句与 C 语言等的 for 语句格式不一样,但都是用来循环处理一组值的。这组值可以是任意字符串的集合(shell 在默认情况下所有变量都是以字符串的形式存储的),它们可以在程序里被列出,更常见的做法是使用 shell 的文件名扩展结果。 for 循环将会重复整个对象列表,依次执行每一个独立对象的循环内容。对象可能是命令行参数、文件名或是任何可以以列表形式建立的东西。

其语法如下:

  1. for variable in values
  2. do
  3. statements
  4. done

  for 命令可以执行指定次数的一个或多个命令。在执行循环时,参数列表 values(可以有多个参数,如val1、val2、val3、…) 中的第一个参数将被赋给变量 variable,然后执行循环体(do 与 done 之间的命令);然后将列表中的第二个参数赋给 variable,依次循环,直到列表中的参数用完。

举个简单的例子:

  1. for name in can you speak English
  2. do
  3. echo $name
  4. done

这段代码将依次打印参数列表中的参数。 关于 for 语句,还有许多其他细节,读者有兴趣可以自行了解。

回到顶部

  • while 与 until 语句

  如果你需要进行循环操作而是先不知道需要循环的次数,可以使用 while 循环,while 循环的语法如下:

  1. while condition
  2. do
  3. statements
  4. done

  until 循环语句的功能与 while 一样,不同的是对于条件判断结果的处理上。until 循环的语法如下:

  1. until condition
  2. do
  3. statements
  4. done

  在 while 和 until 语句中,condition 是判断条件,不同的是,while 语句中,若判断条件为真,则执行循环体;until 语句中,若判断条件为真,则停止执行循环体。

  1. i=1
  2. while [ "$i" -le 10 ]
  3. do
  4. read -p "请输入一个数字:" i
  5. done
  6. echo "$i"

  这段代码从键盘中输入一个数字,直到输入数值大于 10,退出循环并打印最后输入的那个值。

分支

与其他编程语言中的 case 语句类似, shell 中的 case 语句也可以用来进行模式匹配,语法如下:

  1. case var in
  2. pattern [ | pattern ] ... ) statements1;;
  3. pattern [ | pattern ] ... ) statements2;;
  4. ...
  5. esac

 关于 case 的语法,有以下几点需要注意:

  1. case 语句以 case 作为开头,以 esac 作为结尾;
  2. case 语句的每个模式行都是以双分号 ;; 结尾的;
  3. 一个模式行可以合并匹配多个模式,使用 | 符作为分隔;
  4. 一个模式行可以执行多条语句,各语句之间可以使用单分号 ; 隔开,这也是为什么每行的结尾要使用双分号 ;; 作为结束标志的原因;
  5. case 语句支持使用正则表达式作为匹配项,这使得 case 语句的功能更为强大。 ```shell

    判断这个字符是字母还是数字,都不是的话返回

    case $char in [a-z] | [A-Z] ) echo “字符是一个字母”;; [1-9] ) echo “字符是一个数字”;;
  • ) echo “未知类型的字符” esac ```