Shell编程之变量详解
一、什么是变量 在我们上学时,我们就接触数据方程式;例如:已知x=1 y=x+1那么y等于多少,我们毫不犹豫的会算出来2,但是在shell中x就是变量名,那么对应的1就是变量值,在这里的等于号,在shell中称为赋值! 例如:以下在centos7中展示
[root@yankerp ~]# name="yankerp" <--定义变量-变量名为name,对应的变量值名字叫做yankerp [root@yankerp ~]# echo $name <--打印变量值使用echo $变量名 yankerp <--输出结果以上例子就是一个自定义变量 变量赋值方式;先写变量名称,紧接着就是=号 =号的左右不可以有空格。最后是变量值,通过echo $(变量名) 就可以输出name变量的值,变量值一般需要加双引号。 二、变量的类型
export UUU=yankerp 这种变量不会永久的保存!! 如果需要永久的保存上面已经说了在 .bashrc 或者 .bash_profile文件中设置 那么我们怎么看系统的变量呢? 使用set、env、declare命令查看,以下是env查看结果
XDG_SESSION_ID=171 HOSTNAME=yankerp TERM=xterm SHELL=/bin/bash HISTSIZE=3000 SSH_CLIENT=183.202.244.122 12158 22 SSH_TTY=/dev/pts/4 USER=root qq=aaaaaa 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:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=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:*.webm=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/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin PWD=/root LANG=en_US.utf8 SHLVL=1 HOME=/root LOGNAME=root SSH_CONNECTION=183.202.244.122 12158 10.141.58.170 22 LESSOPEN=||/usr/bin/lesspipe.sh %s PROMPT_COMMAND=history -a; printf " 33]0;%s@%s:%s 07" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" XDG_RUNTIME_DIR=/run/user/0 HISTTIMEFORMAT=%F %T _=/usr/bin/envset env daclare的区别 set命令:输出全部的变量; 以下是set输出结果,使用tail查看set命令输出的最后5行等...
[root@yankerp ~]# set | tail -5 { local quoted; _quote_readline_by_ref "$1" ret; printf %s "$ret" } [root@yankerp ~]# set -o | head -5 allexport off braceexpand on emacs on errexit off errtrace off
[root@yankerp ~]# env | tail -5 LESSOPEN=||/usr/bin/lesspipe.sh %s PROMPT_COMMAND=history -a; printf " 33]0;%s@%s:%s 07" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" XDG_RUNTIME_DIR=/run/user/0 HISTTIMEFORMAT=%F %T _=/usr/bin/env 三、自定义环境变量 1、设置环境变量在设置环境变量之前我们需要使用export命令 具体如下:
export 变量名=tom export CSDN=yankerp 以下是自定义全局变量的实例
[root@yankerp ~]# tail -1 /etc/profile <----查看/etc/profile最后一行 export CSDN=yankerp ---<输出此行并保存 [root@yankerp ~]# source /etc/profile <---<使/etc/profile生效 [root@yankerp ~]# echo $CSDN <----在变量前面加上$符号并打印变量值 yankerp <----输出结果 [root@yankerp ~]# env | grep CSDN <----使用env查看环境变量并使用grep过滤CSDN变量值 CSDN=yankerp ----输出结果 2、修改登录提示
[root@yankerp ~]# cat /etc/motd this is a yankerp!!! 登录提示如下:
Last login: Sat Jan 27 23:27:01 2018 from this is a yankerp!!! [root@yankerp ~]# 3、用echo以及printf命令打印出环境变量
[root@yankerp ~]# echo $UID 0 [root@yankerp ~]# echo $USER root [root@yankerp ~]# echo $SHELL /bin/bash [root@yankerp ~]# printf "$HOMEn" /root在以上的printf后面加n是表示换行的意思,printf一般不是经常用,说白了这个命令是为awk打基础。 使用env或set命令显示默认的环境变量
[root@yankerp ~]# env MAIL=/var/spool/mail/root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin CSDN=yankerp PWD=/root LANG=en_US.utf8 SHLVL=1 HOME=/root LOGNAME=root SSH_CONNECTION=183.202.244.122 12120 10.141.58.170 22 LESSOPEN=||/usr/bin/lesspipe.sh %s PROMPT_COMMAND=history -a; printf " 33]0;%s@%s:%s 07" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" XDG_RUNTIME_DIR=/run/user/0 HISTTIMEFORMAT=%F %T 用set命令显示环境变量包括局部变量
[root@yankerp ~]# set BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")问题来了 怎么取消变量呢? 例如:我设置一个环境变量
[root@yankerp ~]# export YANKAI=ywyankerp [root@yankerp ~]# echo $YANKAI ywyankerp [root@yankerp ~]# env | grep YANKAI YANKAI=ywyankerp 现在我们使用unset命令消除变量 如下:
[root@yankerp ~]# unset YANKAI [root@yankerp ~]# echo $YANKAI [root@yankerp ~]# 四、普通变量 1、定义本地变量 本地变量在用户当前的shell脚本中使用,如果在shell中开启另外一个进程或者说退出那么将会失效 普通变量的类型
变量名=yankerp 变量名='yankerp' 变量名="yankerp"变量名一般都是由字母、数字、下划线组成的,变量名不能以数字开头 变量的内容可以用单引号、双引号、引起来,同时也可以不加引号,但是这三者的含义是不一样的。如下:
[root@yankerp ~]# a=192.168.1.10 [root@yankerp ~]# b='192.168.1.10' [root@yankerp ~]# c="192.168.1.10" [root@yankerp ~]# echo "a=$a" a=192.168.1.10 [root@yankerp ~]# echo "b=$b" b=192.168.1.10 [root@yankerp ~]# echo "c=$c" c=192.168.1.10 [root@yankerp ~]# 在以上例子中好像看不出来哪里不一样,说明了将连续普通的字符串的内容赋值给变量,不管用不用引号,只要变量名是什么,它就会打印什么 那么到这里到底有什么区别实例证明如下: 例如:我不用''引号设置变量和用''号设置如下:
[root@yankerp ~]# a=yan ker p -bash: ker: command not found [root@yankerp ~]# a='yan ker p' [root@yankerp ~]# echo $a yan ker p [root@yankerp ~]#经过以上实例我们可以看到,不加单引号设置变量,其中变量名有空格,但是它会报错,如果我们加了单引号,其中变量名有空格,它就会打印出来我们设置的yan ker p; 结论:当我们不加单引号时必须是连续的字符串才可以;如果加了''号那么结论是当变量名写什么那么它就会输出什么。 “”号案例如下:
[root@yankerp ~]# a='yan ker p' [root@yankerp ~]# b="yan ker p" [root@yankerp ~]# echo $a yan ker p [root@yankerp ~]# echo $b yan ker p [root@yankerp ~]#在以上的案例中我们并没有发现''号于“”号有什么区别,但是我们来继续看下面的案例
[root@yankerp ~]# a=$("ls") <----此变量名ls为linux命令 [root@yankerp ~]# echo $a anaconda-ks.cfg总结:""这种定义的方式特点是:输出变量内容时引号变量及命令会经过解析后在输出 把一个变量命令赋值的方法 例如:我们要查询我们的IP地址 我们可以使用ifconfig这个命令来查看,但是我们如何在shell脚本中实现呢? 按照很普通的想法是这样的如下: 在以上脚本中我们就会认为,IP是变量名,ifconfig是变量值,那么我们执行这个脚本echo $IP 那么就会输出ip信息吗?
[root@yankerp Log.sh]# cat test1.sh #!/bin/bash # Sat Jan 27 20:45:40 CST 2018 # User <ywyankerp@163.com> # Version 1.1.0 # This is a cs. IP=ifconfig [root@yankerp Log.sh]# source test1.sh [root@yankerp Log.sh]# echo $IP ifconfig [root@yankerp Log.sh]#我们发现它输出的是ifconfig字符串,为啥? 因为IP=ifconfig在linux中它会很简单的认为ifconfig就是个字符串并不是命令.... 接下来介绍两个符号
变量名=`ifconfig` 变量名=$("ifconfig")我们在上面已经说过""的作用,它是 输出变量内容时引号变量及命令 会经过解析后在输出 脚本内容如下:
[root@yankerp Log.sh]# cat test1.sh #!/bin/bash # Sat Jan 27 20:45:40 CST 2018 # User <ywyankerp@163.com> # Version 1.1.0 # This is a cs. IP=$("ifconfig") [root@yankerp Log.sh]# source test1.sh [root@yankerp Log.sh]# echo $IP eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.141.58.170 netmask 255.255.192.0 broadcast 10.141.63.255 ether 52:54:00:b3:c1:34 txqueuelen 1000 (Ethernet) RX packets 92758 bytes 9588691 (9.1 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 91995 bytes 12612699 (12.0 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0从以上脚本中我们可以看到ifconfig命令已经生效,我们暂时不用管他的排版 同时我们也可以在命令段的前后加``反撇号 这个看个人习惯 我是习惯用反撇号;
[root@yankerp ~]# IP=`ifconfig`举几个例子``
[root@yankerp ~]# SJ=`date +%F`.tar.gz [root@yankerp ~]# echo $SJ 2018-01-28.tar.gz以上date +%f就是一条命令 在这条命令的基础上我们加了``反撇号让它解析同时在后面加了.tar.gz 输出结果为时间+.tar.gz 再次测试如下:
[root@yankerp ~]# YYY=etc_`hostname`.tar.gz [root@yankerp ~]# echo $YYY etc_yankerp.tar.gz [root@yankerp ~]# echo 'yankerp date +%F' yankerp date +%F [root@yankerp ~]# echo "yankerp date +%F" yankerp date +%F [root@yankerp ~]# echo "yankerp `date +%F`" yankerp 2018-01-28注意以上的反撇号 案例1:在正则表达式三剑客中grep命令过滤字符串给加引号
[root@yankerp Log.sh]# cat test <------文本内容如下: yankerp zhangsan lisi wangwu zhouliu zhouwu zhousi CSDN [root@yankerp Log.sh]# aaa=yankerp <----设置变量aaa=yankerp [root@yankerp Log.sh]# grep $aaa test yankerp [root@yankerp Log.sh]# grep '$aaa' test [root@yankerp Log.sh]# grep "$aaa" test yankerp [root@yankerp Log.sh]#案例2:在正则表达式三剑客中awk命令测试
[root@yankerp ~]# EEE=123456 [root@yankerp ~]# awk 'BEGIN {print "$EEE"}' $EEE [root@yankerp ~]# awk 'BEGIN {print '$EEE'}' 123456 [root@yankerp ~]# awk 'BEGIN {print "'$EEE'"}' 123456 [root@yankerp ~]#我们发现和前面的不一样啊 不是说""是解析命令吗 为什么在awk中它是输入什么就输出什么呢,而使用''号在之前是输入什么就输出什么,这就是AWK调用shell变量的特殊用法 声明:以上文章是<<跟着老男孩学Linux运维Shell编程实战>>第三章看完的总结; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |