您的位置:首页 > 运维架构 > Shell

shell 脚本 - 变量

2020-08-08 13:29 871 查看

shell 脚本 - 变量

  • 环境变量
  • 只读变量
  • 位置变量
  • 退出状态码变量
  • 脚本安全和set
  • 变量基础概念

    变量类型

    内置变量(环境变量) ,如:PS1,PATH,UID,HOSTNAME,$,BASHPID,PPID,,BASHPID,PPID,,BASHPID,PPID,?,HISTSIZE 等
    用户自定义变量

    数据类型:字符和数值。数值包含整型、浮点型,bash 不支持浮点数

    变量命名法则

    1 不能使用程序中的关键字和内置变量,如:if,for
    2 只能使用数字、字母及下划线,且不能以数字开头。注意:不支持短横线“-”,和主机名相反
    3 见名知意,建议用英文单词命名,并体现实际作用,最好不要用简写
    4 统一命名规则:驼峰命名法(studentname),大驼峰(StudentName),小驼峰(studentName)
    5 变量名大写:STUDENT_NAME
    6 局部变量小写
    7 函数名小写

    变量定义和应用

    变量的生效范围等标准划分变量类型

    普通变量:生效范围为当前shell 进程;对当前shell 之外的其他shell 进程,包括当前shell 的子shell 进程均无效
    
    环境变量:生效范围为当前shell 进程及其子进程
    
    本地变量:生效范围为当前shell 进程中某代码片段,通常指函数

    变量赋值

    name='value'
    
    value的多种形式
    直接字符串	name='root'
    变量引用	name="$USER"
    命令引用	name=`COMMAND` 或者 name=$(COMMAND)

    需要注意的是:

    变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存。脚本中的变量也会随着脚本结束,自动删除

    变量引用

    $name 或 ${name} 	建议使用${name}
    
    "$name" 弱引用,其中的变量引用会被替换为变量值
    '$name' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

    范例:变量的各种赋值方式和引用

    #变量的赋值方式
    [root@CentOS8 ~]#TITLE='cto'
    [root@CentOS8 ~]#echo $TITLE
    cto
    [root@CentOS8 ~]#TITLE='cto'
    [root@CentOS8 ~]#echo $TITLE
    cto
    [root@CentOS8 ~]#echo "i am $TITLE"
    i am cto
    [root@CentOS8 ~]#echo 'i am $TITLE'
    i am $TITLE
    
    [root@CentOS8 ~]#FILE=`ls /run`
    [root@CentOS8 ~]#echo $FILE
    agetty.reload auditd.pid console cron.reboot cryptsetup dbus faillock fsck initctl initramfs lock log mount NetworkManager plymouth rsyslogd.pid sepermit setrans sshd.pid sssd.pid sudo systemd tmpfiles.d tuned udev user utmp vmware
    
    #变量的引用
    [root@CentOS8 ~]#NAME=dawn
    [root@CentOS8 ~]#AGE=17
    [root@CentOS8 ~]#echo $NAME $AGE
    dawn 17
    [root@CentOS8 ~]#echo $NAME$AGE
    dawn17
    [root@CentOS8 ~]#echo $NAME_$AGE
    17
    [root@CentOS8 ~]#echo ${NAME}_$AGE
    dawn_17
    
    #变量的间接赋值和引用,ps:原变量的值修改后,被赋值的变量的值不会随之变更
    [root@CentOS8 ~]#TITLE=cto
    [root@CentOS8 ~]#NAME=dawn
    [root@CentOS8 ~]#TITLE=$NAME
    [root@CentOS8 ~]#echo $NAME
    dawn
    [root@CentOS8 ~]#echo $TITLE
    dawn
    [root@CentOS8 ~]#NAME=haha
    [root@CentOS8 ~]#echo $NAME
    haha
    [root@CentOS8 ~]#echo $TITLE
    dawn
    
    #利用变量实现动态命令
    [root@CentOS8 ~]#CMD=hostname
    [root@CentOS8 ~]#$CMD
    CentOS8.dawn

    变量的显示和删除

    set		显示已定义的所有变量
    unset <name>	删除变量name

    范例

    [root@CentOS8 ~]#NAME=dawn
    [root@CentOS8 ~]#TITLE=ceo
    [root@CentOS8 ~]#echo $NAME $TITLE
    dawn ceo
    [root@CentOS8 ~]#unset NAME TITLE
    [root@CentOS8 ~]#echo $NAME $TITLE
    
    [root@CentOS8 ~]#

    环境变量

    • 可使子进程(子子孙孙进程)继承父进程的变量,但无法让父进程使用子进程的变量
    • 一旦子进程修改从父进程继承的变量,会将新的值传递给孙子进程,不影响父进程的值
    • 一般只在系统配置文件中使用,在脚本使用较少

    声明赋值引用

    #声明并赋值
    export name=VALUE
    declare -x name=VALUE
    
    #也可先赋值再声明
    name=VALUE
    export name
    
    #变量引用
    $name 或 ${name}

    显示所有环境变量

    [root@CentOS8 ~]#env
    [root@CentOS8 ~]#printenv
    [root@CentOS8 ~]#export
    [root@CentOS8 ~]#declare -x

    删除变量

    unset name

    只读变量

    只能声明定义,后续不能修改和删除,即常量

    声明查看

    #声明
    readonly name  或declare -r name
    
    #查看
    readonly [-p]
    declare -r

    范例

    #声明常量PI
    [root@CentOS8 ~]#readonly PI=3.1415926
    [root@CentOS8 ~]#echo $PI
    3.1415926
    #无法修改常量
    [root@CentOS8 ~]#PI=3.14
    -bash: PI: readonly variable
    #无法删除
    [root@CentOS8 ~]#unset PI
    -bash: unset: PI: cannot unset: readonly variable
    
    #退出当前shell,常量就被销毁了
    [root@CentOS8 ~]#exit

    位置变量

    在bash shell 中内置的变量,在脚本代码中调用通过命令行传递给脚本的参数

    $1,$2,...$n 	对应第1个,第2个等第n个参数,shift [n]换位置
    $0	命令本身,包括路径
    $*	传递给脚本的所有参数,全部参数视为一个字符串
    $@	传递给脚本的所有参数,每个参数视为独立字符串
    $#	传递给脚本的参数的个数
    $$	脚本执行的过程ID号
    
    ps:$@ $* 只有在被双引号抱起来的时候才会有差异

    清空所有位置变量

    set --

    范例

    [root@CentOS8 script]#cat args.sh
    #!/bin/bash
    #********************************************************************
    # Author:dawn
    # Date:2020-08-08 10:21:18
    # FileName:args.sh
    # URL:https://blog.csdn.net/xiao_dan_
    # Version:1.0
    # Description:The test script
    #********************************************************************
    echo "1st arg is $1"
    echo "2st arg is $2"
    echo "3st arg is $3"
    echo "10st arg is ${10}"
    echo "11st arg is ${11}"
    
    echo "\$# The number of arg is $#"
    echo "\$* All args are $*"
    echo "\$@ All args are $@"
    echo "The scriptname is `basename $0`"
    echo "\$\$ PID is $$"
    
    [root@CentOS8 script]#bash args.sh {a..z}
    1st arg is a
    2st arg is b
    3st arg is c
    10st arg is j
    11st arg is k
    $# The number of arg is 26
    $* All args are a b c d e f g h i j k l m n o p q r s t u v w x y z
    $@ All args are a b c d e f g h i j k l m n o p q r s t u v w x y z
    The scriptname is args.sh
    $$ PID is 3052

    范例-@和@ 和@和* 的区别

    #$@ 和$* 的区别 --主要用在轮询的时候
    [root@CentOS8 script]#cat test.sh
    echo "\$* 展示的所有参数:$*"
    for i in "$*";do
    echo $i
    done
    
    echo "\$@ 展示的所有参数:$@"
    for i in "$@";do
    echo $i
    done
    
    [root@CentOS8 script]#bash test.sh dawn li 22 33
    $* 展示的所有参数:dawn li 22 33
    dawn li 22 33
    $@ 展示的所有参数:dawn li 22 33
    dawn
    li
    22
    33

    范例-利用软链接实现同一个脚本不同功能

    [root@CentOS8 script]#vim ln.sh
    #!/bin/bash
    echo $0
    #设置软链接
    [root@CentOS8 script]#ln -snf ln.sh a.sh
    [root@CentOS8 script]#ln -snf ln.sh b.sh
    
    #执行软链接
    [root@CentOS8 script]#bash a.sh
    a.sh
    [root@CentOS8 script]#bash b.sh
    b.sh

    退出状态码变量

    在shell 脚本中使用

    $?
    保存程序执行状态码的相关数字,不同的值反应成功或失败,
    $?
    取值范围在0-255

    $?	上一条命令执行后的状态,0:执行正常,非零为异常,一般结果为1
    
    自定义退出状态码
    exit [n]	n的取值范围在0-255

    范例

    [root@CentOS8 ~]#curl http://www.wangxiaochun.com &> /dev/null
    [root@CentOS8 ~]#echo $?
    0

    ps:

    • 脚本中一旦遇到exit 命令,脚本会立即终止;终止退出状态码取决于exit 命令后的数字
    • 如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

    脚本安全和set

    set

    可用来定制shell 环境

    set 命令实现脚本安全

    -u	在扩展一个没有设置的变量时,显示错误信息,等同set -o nounset
    -e	如果一个命令返回一个非0退出状态值(失败)就退出,等同set -o errexit
    -o	option 显示,打开或关闭选项
    显示选项:set -o
    打开选项:set -o 选项
    关闭选项:set +o	选项
    -x	当执行命令时,打印命令及其参数,类似bash -x

    范例

    [root@CentOS8 ~]#set -o
    allexport      	off
    braceexpand    	off
    emacs          	on
    ……省略……

    $- 变量

    h	hashall,打开选项后,shell 会将命令所在的路径hash 下来,避免每次都要查询。通过set +h 将h 选项关闭
    i	interactive-comments,包含这个选项说明当前的shell 是一个交互式的shell。所谓交互式shell,在脚本中,i 选项是关闭的
    m	moniter,打开监控模式,可通过job control来控制进程的停止、继续,后台或前台执行等
    B	braceexpand,大括号扩展
    H	history,H选项打开,可展开历史列表的命令,可通过感叹号! 来完成,例如:!! 返回最近一个历史命令,!n 返回第n 个历史命令

    范例

    [root@CentOS8 ~]#echo $-
    himBHs
    [root@CentOS8 ~]#echo {1..10}
    1 2 3 4 5 6 7 8 9 10
    [root@CentOS8 ~]#set +B
    [root@CentOS8 ~]#echo $-
    himHs
    [root@CentOS8 ~]#echo {1..10}
    {1..10}
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: