zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    二分图最大匹配的König定理及其证明
    HDOJ 2389 Rain on your Parade
    HDOJ 1083 Courses
    HDOJ 2063 过山车
    POJ 1469 COURSES
    UESTC 1817 Complete Building the Houses
    POJ 3464 ACM Computer Factory
    POJ 1459 Power Network
    HDOJ 1532 Drainage Ditches
    HDU 1017 A Mathematical Curiosity
  • 原文地址:https://www.cnblogs.com/liujunjun/p/11997307.html
Copyright © 2011-2022 走看看