这篇文章上次修改于 1689 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

变量

自定义变量

  • 语法格式为 name=[value]
  • 如果value没有指定,变量将被设定为空字符串
  • 使用<$变量名称>来调用变量的值
  • 变量名称为字母、数字及下画线的组合,但首字母不能是数字
  • 通过typeset为变量添加只读属性可以防止误操作

    [root@Hyui-VM ~]# NAME=nginx
    [root@Hyui-VM ~]# echo $NAME
    nginx
    [root@Hyui-VM ~]# typeset -r NAME  #设定只读属性
    [root@Hyui-VM ~]# NAME=apache
    -bash: NAME: readonly variable
  • 如何在不赋值的情况下预先定义一个变量呢?

    [root@Hyui-VM ~]# declare INT_NUMBER  #使用declare进行定义
  • 如何将INT_NUMBER设定为整型呢?

    [root@Hyui-VM ~]# typeset -i INT_NUMBER  #设定为整型
    [root@Hyui-VM ~]# INT_NUMBER=centos  #给INT_NUMBER赋一个字符型的值
    [root@Hyui-VM ~]# echo $INT_NUMBER  #输出就只能是0
    0
    [root@Hyui-VM ~]# INT_NUMBER=1000  #赋值为整型
    [root@Hyui-VM ~]# echo $INT_NUMBER  #成功输出整型数字
    1000
  • read命令
  • read从标准输入中取得变量的值
  • 可以通过-p添加提示信息

    [root@Hyui-VM ~]# read R_NUMBER  #运行此命令后输入要赋值给R_NUMBER的值
    100
    [root@Hyui-VM ~]# echo $R_NUMBER
    100
    [root@Hyui-VM ~]# read -p "请输入一个数字:" R_NUMBER  #带提示信息的
    请输入一个数字:200
    [root@Hyui-VM ~]# echo $R_NUMBER
    200
    [root@Hyui-VM ~]# set | grep R_NUMBER  #set可以查看当前系统中所有的变量和值,写一个管道显示出R_NUMBER的值
    R_NUMBER=200
    [root@Hyui-VM ~]# unset R_NUMBER  #删除R_NUMBER变量

    变量的使用范围

  • export的使用

    [root@Hyui-VM ~]# export NAME=nginx  #直接定义环境变量

    环境变量

  • Bash预设了多种变量,可以直接调用这些变量
    变量名称含 义变量名称含 义
    BASHPID当前Bash进程的进程号UID当前用户的ID号
    GROUPS当前用户所属组的ID号HISTSIZE命令历史的记录条数
    HOSTNAME当前主机的主机名称HOME当前命令的家目录
    PWD当前的工作目录PATH命令搜索路径
    OLDPWD前一个工作目录PS1主命令提示符
    RANDOM0~32767之间的随机数PS2次命令提示符
  • PATH是一个目录的集合

    [root@Hyui-VM ~]# echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  • 对于PATH的修改,切勿给PATH赋新值

    [root@Hyui-VM ~]# PATH=/root  #给PATH赋值为/root,之后运行ls的时候系统会去/root目录下寻找ls,导致无法运行
    [root@Hyui-VM ~]# ls
    -bash: ls: command not found
    #重新登陆终端便可复原(只要不通过写入文件的方式永久保存入环境变量)
  • 那么我们如何在原有的路径上追加目录呢?

    [root@Hyui-VM ~]# PATH=$PATH:/root  #这样就可以
    [root@Hyui-VM ~]# echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root

    位置变量

  • 位置变量可以调用运行脚本时不同位置的参数,使用空格分隔,$0代表当前Shell程序文件的名称,$1~$9分别表示脚本后第一个到第九个参数。
  • $#代表Shell所有参数的个数
  • $*和$@表示所有参数的内容
  • $$表示进程的ID号码
  • $?表示程序的退出代码
  • 写一个脚本:

    [root@Hyui-VM ~]# vim test.sh
    #/bin/bash
    echo "这个是文件名称:$0"
    echo "这个是第一个值:$1"
    echo "这个是第二个值:$2"
    echo "这个是第三个值:$3"
    echo "这个是参数的个数:$#"
    echo "所有参数的内容:$*"
    echo "所有参数的内容:$@"
    echo "当前进程号:$$"
  • 运行这个脚本

    [root@Hyui-VM ~]# chmod +x test.sh
    [root@Hyui-VM ~]# ./test.sh a b c  #使用abc三个参数
    这个是文件名称:./test.sh
    这个是第一个值:a
    这个是第二个值:b
    这个是第三个值:c
    这个是参数的个数:3
    所有参数的内容:a b c  #$*所表示的所有参数的内容为'a b c'
    所有参数的内容:a b c  #$@所表示的所有参数的内容为'a' 'b' 'c'
    当前进程号:19163

    变量的展开替换

  • Linux使用${变量名}的形式展开变量的值

    [root@Hyui-VM ~]# NAME=hyui
    [root@Hyui-VM ~]# echo ${NAME}
    hyui
  • 除此之外还有变量展开功能,格式如下

    ${varname:-word}  #如果varname存在且非null,则返回其值,否则返回word
    ${varname:=word}  #如果varname存在且非null,则返回其值,否则设定为word
    ${varname:?message}  #如果varname存在且非null,则返回其值,否则显示varname:message
    ${varname:+word}  #如果varname存在且非null,则返回word,否则返回null

    示例

    [root@Hyui-VM ~]# echo ${NAME:-no user}; echo ${NAME}
    hyui
    hyui
    [root@Hyui-VM ~]# echo ${NAME0:-no user}; echo ${NAME0}
    -no user
    -no user
    [root@Hyui-VM ~]# echo ${NAME:=no user}; echo ${NAME}
    hyui
    hyui
    [root@Hyui-VM ~]# echo ${NAME0:=no user}; echo ${NAME0}
    -no user
    -no user
    [root@Hyui-VM ~]# echo ${NAME:?no defined}; echo ${NAME}
    hyui
    hyui
    [root@Hyui-VM ~]# echo ${EMAN:?no defined}; echo ${EMAN}
    -bash: EMAN: no defined
    [root@Hyui-VM ~]# echo ${NAME:+OK}; echo ${NAME}
    OK
    hyui
    [root@Hyui-VM ~]# echo ${EMAN:+ERROR}; echo ${EMAN}
    

    数组

  • Bash提供了很多数组变量功能,数组中所有变量都会编录成索引,数组的索引是从0开始的整数,没有大小限制。
  • 有两种方式创建数组变量,分别如下

    [root@Hyui-VM ~]# A[1]=11
    [root@Hyui-VM ~]# A[2]=22
    [root@Hyui-VM ~]# A[3]=33
    [root@Hyui-VM ~]# echo ${A[1]},${A[2]},${A[3]}
    11,22,33
    [root@Hyui-VM ~]# echo ${A[1]}:${A[2]}:${A[3]}
    11:22:33
    [root@Hyui-VM ~]# B=(aa bbb cccc)
    [root@Hyui-VM ~]# echo ${B[0]},${B[1]},${B[2]}
    aa,bbb,cccc
  • 使用*和@两个符号将调出所有数组的成员

  • 22 33
    [root@Hyui-VM ~]# echo ${A[@]}
  • 22 33

  • 使用${#name[subscript]}可以返回${name[subscript]}的长度

    [root@Hyui-VM ~]# echo "length of B_0 is: ${#B[0]}"
    length of B_0 is: 2
    [root@Hyui-VM ~]# echo "length of B_1 is: ${#B[1]}"
    length of B_1 is: 3
    [root@Hyui-VM ~]# echo "length of B_2 is: ${#B[2]}"
    length of B_2 is: 4
    [root@Hyui-VM ~]# echo ${#B[*]}
    3

    算术运算与测试

    算术运算

  • 使用$((expression))语法格式可以实现整数级的算术运算功能

    [root@Hyui-VM ~]# echo $((1+2))  #加法运算
    3
    [root@Hyui-VM ~]# echo $((2-1))  #减法运算
    1
    [root@Hyui-VM ~]# echo $((10/2))  #除法运算
    5
    [root@Hyui-VM ~]# echo $((3*2))  #乘法运算
    6
    [root@Hyui-VM ~]# echo $((7%3))  #取余运算
    1
    [root@Hyui-VM ~]# x=5
    [root@Hyui-VM ~]# y=3
    [root@Hyui-VM ~]# echo $((x**y))  #幂运算
    125

    测试

  • 使用Bash内置命令可以实现测试工作或使用测试表达式
    测试选项含义测试选项含义
    -d测试目录-e测试文件
    -f测试普通文件是否存在-r文件是否可读
    -w文件是否存在且可写-x文件是否存在且可执行
    -s文件是否存在且非空-h文件是否为链接文件
    -n字符串长度非0-z字符串长度为0
    [root@Hyui-VM ~]# test -d /etc/ && echo "True" || echo "False"  #可以使用test进行测试
    True
    [root@Hyui-VM ~]# test -d /etc/passwd && echo "True" || echo "False"
    False
    [root@Hyui-VM ~]# [ -d /etc/ ] && echo "True" || echo "False"
    True
    [root@Hyui-VM ~]# [ -e /etc/passwd ] && echo "True" || echo "False"
    True
    [root@Hyui-VM ~]# [ -f /etc/password ] && echo "True" || echo "False"
    False
    [root@Hyui-VM ~]# [ -h /etc/grub.conf ] && echo "True" || echo "False"
    False
    [root@Hyui-VM ~]# [ -n $PATH ] && echo "True" || echo "False"
    True
    [root@Hyui-VM ~]# [ -z $ab ] && echo "True" || echo "False"  #ab变量没有定义
    True
  • Bash中的大于小于等于都有对应选项所对应
    -eq等于
    -ge大于等于
    -gt大于
    -le小于等于
    -lt小于
    -ne不等于

    使用示例:

    [root@Hyui-VM ~]# [ 233 -eq 233 ] && echo "True" || echo "False"
    True