• SHELL脚本--变量


    环境变量                    

    环境变量就是运行在"环境"上下文的,在这个上下文都可以引用。例如,常见的cd、ls等命令严格来说应该使用绝对路径如/bin/ls来执行,由于/bin目录加入到了PATH环境变量中,系统自己会去寻找PATH下的路径是否有该命令。

    环境变量常用大写字母表示。常见的环境变量有HOSTNAME、SHELL、HISTSIZE、USER、PATH、PWD、LANG、HOME、LOGNAME。分别表示当前主机名、SHELL的路径即bash的类型、history保存多少记录、当前用户名、自动搜索路径、当前目录、使用的语系(临时修改语系时就改这个变量)、当前用户的家目录、当前登录的用户。

    使用env或者export可以查看当前用户的环境变量。

    [root@localhost ~]# env
    HOSTNAME=localhost.localdomain
    TERM=vt100
    SHELL=/bin/bash
    HISTSIZE=1000
    SSH_CLIENT=192.168.1.5 50651 22
    QTDIR=/usr/lib64/qt-3.3
    QTINC=/usr/lib64/qt-3.3/include
    SSH_TTY=/dev/pts/0
    USER=root
    LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
    MAIL=/var/spool/mail/root
    PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
    PWD=/root
    LANG=zh_CN.UTF-8
    HISTCONTROL=ignoredups
    SHLVL=1
    HOME=/root
    LOGNAME=root
    QTLIB=/usr/lib64/qt-3.3/lib
    CVS_RSH=ssh
    SSH_CONNECTION=192.168.1.5 50651 192.168.1.213 22
    LESSOPEN=||/usr/bin/lesspipe.sh %s
    G_BROKEN_FILENAMES=1
    _=/bin/env

    使用echo可以输出变量的值。

    [root@localhost ~]# echo $PATH
    /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

    例如,在PATH环境变量中新加入一个目录/usr/local/mysql/bin。

    [root@localhost ~]# PATH=/usr/local/mysql/bin:$PATH
    [root@localhost ~]# echo $PATH
    /usr/local/mysql/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

    这里也能看到两个PATH第一个没使用$,第二个使用了。当对变量本身进行操作,则不使用$,当对变量值进行操作,则使用$

    普通变量                            

    脚本语言是弱类型的语言,变量通常不需要特地声明甚至不需要初始化,在脚本运行时由解释器进行解释运算,解释器知道变量在什么时候是什么类型,所以直接赋值使用即可。bash中,变量默认都是字符串类型,不论是否使用引号赋值,都以字符串方式存储。

    1.变量赋值方式: str=value 。注意等号左右没有空格。如果有空格就是进行比较运算符的比较运算了。

    2.变量引用方式:$str或者${str},例如 echo "the var is ${str}" 。

    [root@localhost ~]# str='Hello World!'
    [root@localhost ~]# echo "We will say ${str}"
    We will say Hello World!

    释放变量: unset str ,注意变量名前不加前缀$。

    [root@localhost ~]# unset str

    查看所有的变量:不接任何参数的set或者declare命令,输出结果中包含了普通变量和环境变量。

     定义只读变量: readonly str 。这时将无法修改变量值也无法unset变量,只有重新登录shell才能继续使用只读变量。

     临时将普通变量升级为环境变量: export str 或者赋值时 export str="value" ,这样$str就可以在当前shell和子shell中使用,但是退出脚本或者重新登录shell都会取消export效果。

    [root@localhost ~]# str='Hello World!';echo $str
    Hello World!
    [root@localhost ~]# bash
    [root@localhost ~]# echo ${str}
    
    [root@localhost ~]# 

    在子shell中查看变量,结果竟然没有该变量。这是因为$str的作用域只在当前shell,要想在子shell中也能引用普通变量,则需要使用export升级为环境变量。

    [root@localhost ~]# exit
    exit
    [root@localhost ~]# echo $str
    Hello World!
    [root@localhost ~]# export str
    [root@localhost ~]# echo $str
    Hello World!

    修改变量的生命周期和作用域                      

    普通的变量在脚本结束或退出登录后就失效,并且只对当前shell有效,其他用户和当前用户的子shell都无法使用。

    使用export可以升级为临时局部的环境变量,只对当前用户的当前shell和子shell有效,退出脚本和退出登录后也失效。

    如果想要设置永久的且全局的变量,一种方法是将变量的设置语句放入到/etc/profile文件中,因为每个用户登录时,都会调用该文件并执行其中的语句。如果想立即加载此文件中的配置使得临时添加的设置立即生效,只需source该文件即可。

    [root@localhost ~]# source /etc/profile
    [root@localhost ~]# 

    /etc/profile文件是bash的全局配置文件,还有每个用户的配置文件~/.bash_profile,此文件中的变量将只对对应的用户生效。

    此外,还有几个配置bash环境配置文件,具体的见bash环境配置流程

    获取变量的长度                            

     在使用"${}"方式引用变量时,变量名前加上#就可以查看该变量的字符长度。空格也算入长度。例如:

    [root@localhost ~]# echo ${#str}
    12
    [root@localhost ~]# echo ${#PATH}
    113

    declare声明变量                            

    declare [+/-][选项] 变量名
    
    选项说明:
    
    -/+:给变量设定类型属性,取消给变量设定的类型属性
    
    -i:声明为整型
    
    -x:声明为环境变量
    
    -p:显示变量名和值

    例如,声明一个环境变量 declare -x str ,取消该变量 declare +x str  

    位置变量和特殊变量                        

    $?:上一条代码执行的回传指令,回传0表示标准输出,即正确执行,否则为标准错误输出。
    
    $$:当前shell的PID。除了执行bash命令和shell脚本时,$$不会继承父shell的值,其他类型的子shell都继承。
    
    $BASHPID:当前shell的PID,这和"$$"是不同的,因为每个shell的$BASHPID是独立的。而"$$"有时候会继承父shell的值。
    
    $!:最近一次执行的后台进程PID。
    
    $#:统计参数的个数。
    
    $@:所有单个参数,如"a""b""c""d"。
    
    $*:所有参数的整体,如“abcd”。
    
    $0:脚本名。
    
    $1……$n:参数位置。

    使用下面的脚本来验证位置变量和特殊变量。

    [root@localhost ~]# cat var.sh 
    #!/bin/bash
    
    # 测试各种变量的作用,包括预定义和自定义变量
    echo '$?:'$?
    echo '$$:'$$
    echo '$!:'$!
    echo '$#:'$#
    echo '$@:'$@
    echo '$*:'$*
    echo '$0:'$0
    echo '$1:'$1
    echo '$2:'$2
    echo '$3:'$3
    echo '$4:'$4
    [root@localhost ~]# bash var.sh a b c d e
    $?:0
    $$:1960
    $!:
    $#:5
    $@:a b c d e
    $*:a b c d e
    $0:var.sh
    $1:a
    $2:b
    $3:c
    $4:d

    shift轮替变量                            

    使用 shift [N] 可以指定参数轮替,每执行一次 shift N 就踢掉N个参数,默认N为1。

    例如在脚本中:

    echo $1   # # 输出第一个参数值
    shift 2   # # 踢掉前两个参数,第三个参数变成$1
    echo $1   # # 此时$1的值为第三个参数的值
    shift     # # 又踢掉一个参数,第四个参数变成$1
    echo $1   # # 输出第四个参数

    shell其他基础                            

     变量中字符的长度: ${#VARNAME} 

     变量赋值等:

    ${parameter:-word}:如果parameter为空或未定义,则变量展开为“word”;否则展开为parameter的值;
    
    ${parameter-word}:和${parameter:-word}几乎等价,除了parameter设置了但为空时,变量的结果将是null,而非word。在/etc/init.d/httpd中有此用法。
    
    ${parameter:+word}:如果parameter为空或未定义,不做任何操作,即仍然为空;否则展开为“word”值;
    
    ${parameter:=word}:如果parameter为空或未定义,则变量赋值(注意是赋值,不是展开)为“word”,否则为parameter自身;
    
    ${parameter=word}:在man bash里没有该定义,但是经测试,等价于${para:=word}。
    
    ${parameter:offset}:取子串,从offset处的后一个字符开始取到最后一个字符;
    
    ${parameter:offset:length}:取子串,从offset处的后一个字符开始,取lenth长的子串;

    其中 ${parameter:-word} 最常用,最后两个是截取字符串的,偶尔也会用到。

     脚本配置文件

    配置文件中的变量值可以在脚本中被使用

    要在脚本中调用配置文件,直接使用 source config_file 或 . config_file 

    服务启动脚本支持配置文件:/etc/sysconfig/服务脚本同名的配置文件

    局部变量,在函数中定义局部变量使其不影响函数外的同名变量

    local VAR_NAME=

    命令mktemp创建临时文件或目录

    mktemp [-d] /tmp/file.XX   # X指定越多,随机生成的后缀就越长,其中-d表示创建临时目录。

    例如:

    [root@localhost ~]# mktemp haha.XXX
    haha.0Or
    [root@localhost ~]#  mktemp -d haha.XXX
    haha.AiW

    变量的切分、提取和替换                      

    其实是对变量实现的功能,只是使用文件名的说法比较典型,且容易理解它的用途。

    例如,将文件名"Linux.docx.jpg"存放到变量file_name中,然后执行从左向右或从右向左的删除或贪婪删除。

    [root@localhost ~]# file_name="Linux.docx.jpg"
    [root@localhost ~]# file_name_greedy=${file_name%%.*}
    [root@localhost ~]# file_name_nongreedy=${file_name%.*}
    [root@localhost ~]# extention_name_greedy=${file_name##*.}
    [root@localhost ~]# extention_name_nongreedy=${file_name#*.}
    [root@localhost ~]# echo -e "${file_name_greedy}
    ${file_name_nongreedy}
    ${extention_name_greedy}
    ${extention_name_nongreedy}"
    Linux
    Linux.docx
    jpg
    docx.jpg

    ${var%%.*} 和 ${var%.*} 中的 %%.* 表示从右向左匹配 .* 并删除,由于Linux.docx.jpg有两种符合条件的匹配:".jpg"和".docx.jpg",所以使用两个"%%"表示贪婪删除,即删除最长匹配".docx.jpg"。可以使用一个%表示非贪婪删除,表示删除最短的匹配即".jpg"。

     ${var##*.} 和 ${var#*.} 中的 ##*. 表示从左向右匹配 *. 并执行贪婪删除,即删除"Linux.docx.",同理 #*. 表示非贪婪删除,即删除"Linux."。

     除了删除,还可以实现提取和替换的功能。

    [root@localhost ~]# echo "${file_name:0:5}"     
    Linux
    [root@localhost ~]# echo "${file_name:6:4}"
    docx
    [root@localhost ~]# echo "${file_name/jpg/pdf}"
    Linux.docx.pdf
    [root@localhost ~]# echo "${file_name//jpg/pdf}"
    Linux.docx.pdf

    不错的功能是替换。有时候想要删除PATH环境变量中的某个路径,可以使用变量替换的功能,似乎没法使用变量切分来实现。例如:

    [root@localhost ~]# echo $PATH
    /usr/local/mysql/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

    注意,由于可能多次读取了配置文件,导致PATH中出现了重复的路径。现在想删除其中一个路径。使用下面的命令就可以实现路径删除,注意其中使用了转义符号,并且变量替换的替换值留空了表示删除前面匹配的部分。

    [root@localhost ~]# PATH=${PATH/:/usr/local/mysql/bin/}
    [root@localhost ~]# echo $PATH
    /usr/local/mysql/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
  • 相关阅读:
    单例模式 异常抛出
    「分块系列」数列分块入门7 解题报告
    「分块系列」数列分块入门4 解题报告
    「分块系列」数列分块入门5 解题报告
    「分块系列」数列分块入门6 解题报告
    「分块系列」数列分块入门3 解题报告
    「分块系列」数列分块入门2 解题报告
    「分块系列」数列分块入门1 解题报告
    「黑科技」查错神器——对拍
    「洛谷P1196」「NOI2002」银河英雄传说 解题报告
  • 原文地址:https://www.cnblogs.com/liujunjun/p/11997307.html
Copyright © 2020-2023  润新知