一、变量类型

环境变量

生效范围为当前shell,该shell之后生成的子shell都会带有该变量内容,但是该shell子shell定义的全局变量不会继承给上级shell

  1. [root@localhost ~]# export a=c
  2. [root@localhost ~]# echo $a
  3. c
  4. [root@localhost ~]# bash
  5. [root@localhost ~]# echo $a
  6. c
  7. [root@localhost ~]# export b=v
  8. [root@localhost ~]# echo $b
  9. v
  10. [root@localhost ~]# exit
  11. exit
  12. [root@localhost ~]# echo $b

局部变量

只在当前shell中生效,不会对子shell生效

  1. [root@localhost ~]# a=c
  2. [root@localhost ~]# bash
  3. [root@localhost ~]# echo $a

位置变量

根据参数的位置,定义变量名称,$1$2$3…

  1. $1 # 第一个参数
  2. $2 # 第二个参数
  3. $10 # 10之后的变量都需要使用 {} 来对变量名称扩起,为了生命主体
  4. $@ # 输出所有参数
  5. $# # 输出位置参数个数
  6. $* # 与 $@ 差不多相同
  7. [root@localhost ~]# cat sh.sh
  8. #!/bin/bash
  9. echo $1
  10. echo $2
  11. echo ${10}
  12. echo $@
  13. echo $#
  14. echo $*
  15. [root@localhost ~]# bash sh.sh a b c d e f j l z m c
  16. a
  17. b
  18. m
  19. a b c d e f j l z m c
  20. 11
  21. a b c d e f j l z m c

$@ 与 $#的不同
  1. # 当我们在 shell 脚本中定义了循环主体为 $@ 后那么输出的结果就是单个的字符进程处理
  2. # 当我们在 shell 脚本中定义了循环主题为 $* 后那么输出结果就是所有字符串一起输出,作为一个整体
  3. [root@localhost ~]# cat sh.sh
  4. #!/bin/bash
  5. for i in "$@"
  6. do
  7. echo $i
  8. done
  9. for j in "$*"
  10. do
  11. echo $j
  12. done
  13. [root@localhost ~]# bash sh.sh a b c d e f g
  14. a
  15. b
  16. c
  17. d
  18. e
  19. f
  20. g
  21. a b c d e f g

二、变量的基本使用

1、命名规则

硬性标准
  • 不能使用 shell 的保留字及内置变量进行赋值,例如 for if 等
  • 变量名必须以数字或字母以及下划线,变量名中不可以有 - 来作为变量名

    隐性标准
  • 使用大驼峰模式 NameIs 或者小驼峰 nameIs 来命名变量

  • 在命名变量时不要使用简写,要使变量名在其他人使用时同样可以一眼知意
  • 局部变量小写,环境变量大写

    2、赋值方式

    ```

    使用字符串直接赋值

    [root@localhost ~]# Name=”My name is jason_chen” [root@localhost ~]# echo $Name My name is jason_chen

变量之间赋值

[root@localhost ~]# name=”chen” [root@localhost ~]# Name=$name [root@localhost ~]# echo $Name chen

使用 `` 反撇号赋值命令执行结果

[root@localhost ~]# ls_data=ls [root@localhost ~]# echo $ls_data anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public sh.sh Templates Videos

变量追加值

[root@localhost ~]# Name=chen [root@localhost ~]# age=19 [root@localhost ~]# Name+=$age [root@localhost ~]# echo $Name chen19

[root@localhost ~]# Name=chen [root@localhost ~]# Name+=:$age [root@localhost ~]# echo $Name chen:19

  1. <a name="LPVHM"></a>
  2. #### 3、变量的引用方式

使用 ${} 进行调用变量,相当于声明变量主体来进行调用

[root@localhost ~]# echo ${Name} chen

使用 “” 调用变量,变量在 “” 会输出变量内存储的内容

[root@localhost ~]# echo “$Name” chen

使用 ‘’ 调用变量,变量在 ‘’ 不会输出存储内容,只会将变量名相当于一个字符串进行输出

[root@localhost ~]# echo ‘$Name’ $Name

如果想要输出两个变量的组合,但是如果中间有特殊字符将两个变量隔开后,那么系统在识别变量的时候将会识别到 $Name_ 而不是 $Name 所以输出结果就只有 $age 的内容

[root@localhost ~]# echo $Name_$age 19

使用 ${} 将变量扩起,这样就不会造成系统识别变量错误的情况了

[root@localhost ~]# echo ${Name}_$age chen_19

直接调用与加上双引号调用的区别,根据变量名直接调用 echo 只是将结果整体输出,作为一个整体的字符串,而如果加上双引号的话输出结果会根据位置来单个输出

[root@localhost ~]# echo $ls_data anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public sh.sh Templates Videos [root@localhost ~]# echo “$ls_data” anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public sh.sh Templates Videos

<a name="MyM38"></a>
#### 5、删除变量

[root@localhost ~]# Name=chen [root@localhost ~]# echo $Name chen [root@localhost ~]# unset Name [root@localhost ~]# echo $Name

<a name="6b6F2"></a>
#### 6、状态码显示

$? 的执行,成功后返回结果为 0,失败后返回结果为 1-255

[root@localhost ~]# ls /date/ error.log seccess.log [root@localhost ~]# echo $? 0

此时我的 / 目录下并没有 /aaa 目录,所以在查看一个不存在的目录时当然会报错

[root@localhost ~]# ls /aaa ls: cannot access /aaa: No such file or directory [root@localhost ~]# echo $? 2

$? 的使用,通过 if 直接来判断 $? 的值,来返回结果

[root@localhost ~]# ls /aaa; if [ $? -eq 0 ];then echo “yes”; else echo “no”; fi ls: cannot access /aaa: No such file or directory no [root@localhost ~]# ls /date; if [ $? -eq 0 ];then echo “yes”; else echo “no”; fi error.log seccess.log yes

自定义返回值

如果自定义返回值后,不论你的命令执行成功与否都会返回自己定义的返回值,在脚本中使用该 exit 命令来判断脚本执行状态是很有用的哇!

[root@localhost ~]# (ls /data/;exit 100) ls: cannot access /data/: No such file or directory [root@localhost ~]# echo $? 100 [root@localhost ~]# (ls /date;exit 100) error.log seccess.log [root@localhost ~]# echo $? 100

<a name="3QFdi"></a>
## 五、逻辑运算
<a name="nsmU5"></a>
#### 1、算数符
  • / % # 乘,除,(取余取模)
    • 加、减

      i++ i— # 自增、自减 ++i —i # 自增、自减 i++与++i的区别 [root@localhost ~]# i=1;let var=i++;echo $var 1 [root@localhost ~]# i=1;let var=++i;echo $var 2 = = /= %= += -= <<= >>= &= ^= |= <<= >>= # 是二进制移位 ! ~ # 取反 * # 乘方 << >> # 移位 <= >= < > # 大于小于 == != # 等于,不等于 & # and 符号 | # or 符号 ^ # 异或符号 && # 逻辑 and 符号 第一个结果为真,第二个必须执行运算
                    第一个结果为假,结果为0,不执行第二命令
      
      || # 逻辑 or 符号 第一个结果为真,第二个不须执行运算
                    第一个结果为假,第二个执行运算
      
      <a name="2lcsw"></a>
      #### 2、计算方式
      

      let 计算方式

      [root@localhost ~]# let var=1+1 [root@localhost ~]# echo $var 2

(()) 计算方式

[root@localhost ~]# ((var=1*3)) [root@localhost ~]# echo $var 3

$[] 计算方式

[root@localhost ~]# var=$[1*4] [root@localhost ~]# echo $var 4

<a name="0sw0H"></a>
#### 3、随机数生成器

$RANDOM

生成一个 0-50 的随机数

[root@localhost ~]# echo $((RANDOM%50)) 26 [root@localhost ~]# echo $[RANDOM%50] 45

<a name="49SWK"></a>
#### 4、逻辑运算

& and 符号,前一个命令执行后,后一个才可以继续执行 | or 符号,前一个执行后一个就不会执行 ^ 异或符号,根据二进制取出异或值

<a name="FnuvW"></a>
#### 5、条件测试运算

test [expression] [ expression ] # 与 test 相同 [[ expression ]] # []的升级版

-a # 测试文件是否存在 -b # 测试文件是否为块设备文件 -c # 测试文件是否为字符设备文件 -d # 测试文件是否为目录 -e # 测试文件是否存在 -f # 测试文件是否为普通文件 -h # 测试文件是否为链接文件 -L # 与 -h 相同 -r # 测试我呢见是否刻度 -s # 测试文件是否为空 -w # 测试文件是否可写 -x # 测试文件是否可执行 -z # 测试文件是否为空 -n # 测试文件是否不为空 -v # 测试变量是否定义

<a name="v5mhA"></a>
##### 变量测试

-v 测试变量是否定义

[root@DNS ~]# test -v $b [root@DNS ~]# echo $? 0 [root@DNS ~]# b=10 [root@DNS ~]# test -v $b [root@DNS ~]# echo $? 1

[root@DNS ~]# [[ -v $b ]] [root@DNS ~]# echo $? 1

[root@DNS ~]# [ -v $b ] [root@DNS ~]# echo $? 1

<a name="kWywJ"></a>
##### 数值测试

-eq 是否等于 -lt 是否小于 -le 是否小于等于 -gt 是否大于 -ge 是否大于等于 -ne 是否不等于

算数表达比较

== 等于 != 不等于 <= 小于等于

= 大于等于 大于 < 小于

字符串表达比较

-z 测试字符串是否为空,没定义或者为空为真,只要定义不空就是假

[root@DNS ~]# [ -z $x ] [root@DNS ~]# echo $? 0 [root@DNS ~]# x=10 [root@DNS ~]# [ -z $x ] [root@DNS ~]# echo $? 1

-n 测试字符串是否不空,没定义或者为空为假,只要定义不空就是真

变量必须要加双引号,因为如果不加双引号 -n 就是判断的字符串大于 0,即为真,如果加上双引号,那么 -n 选项判断的就是该变量内的数据,而不是变量名本身。

[root@localhost ~]# [ -n “$x” ] [root@localhost ~]# echo $? 1 [root@localhost ~]# x=asd [root@localhost ~]# [ -n “$x” ] [root@localhost ~]# echo $? 0 ```

6、() 与 { } 执行命令的不同

  • () 会创建一个子进程来执行括号中的命令,更加安全,会继承父进程非环境变量的变量。
  • {} 在当前进程执行,会修改当前的 shell 环境。

    7、组合测试条件

    只支持 [] 不支持 [[ ]]
    -a 并且,按位与
    -o 或者,按位或