1. 程式人生 > >Shell編程之變量(詳解)

Shell編程之變量(詳解)

export oca shel overruns 當我 nbsp 正則表達式 通過 onf

一、什麽是變量

在我們上學時,我們就接觸數據方程式;例如:已知x=1 y=x+1 那麽y等於多少,我們毫不猶豫的會算出來2,但是在shell中x就是變量名,那麽對應的1就是變量值,在這裏的等於號,在shell中稱為賦值!
x=1 x(變量名) =(賦值) 1(變量值)

例如:以下在centos7中展示

[root@yankerp ~]# name="yankerp"   <--定義變量-變量名為name,對應的變量值名字叫做yankerp  
[root@yankerp ~]# echo $name     <--打印變量值使用echo $變量名  
yankerp                          
<--輸出結果

以上例子就是一個自定義變量
變量賦值方式;先寫變量名稱,緊接著就是=號 =號的左右不可以有空格。最後是變量值,通過echo $(變量名) 就可以輸出name變量的值,變量值一般需要加雙引號。

二、變量的類型
變量可以分為兩種類型:環境變量(全局變量) 普通變量(局部變量)
環境變量一般使用export內置命令導出的變量,用於定義shell運行環境,保證shell命令能夠正確執行,shell通過環境變量來確定登錄的用戶名等信息,所有的環境變量都是系統的全局變量。
環境變量可以在命令行中創建,但是當用戶退出命令行時這些變量將會丟失,如果需要永久保存環境變量,那麽就可以在用戶家目錄下的.bash_profile 或者 .bashrc 按照系統的規範在設置環境變量時所有的環境變量名采用大寫的方式;


例如:我現在要設置一個環境變量如下:

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 "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}" XDG_RUNTIME_DIR=/run/user/0 HISTTIMEFORMAT=%F %T _=/usr/bin/env

set env daclare的區別

set命令:輸出全部的變量;
env命令:只輸出全局變量;
declare命令:輸出全部的變量、函數、整數和已經導出的變量;
set -o命令:顯示bash shell的所有參數配置信息;

以下是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 "\033]0;%s@%s:%s\007" "${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 "$HOME\n"  
/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 "\033]0;%s@%s:%s\007" "${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 ~]#   

在以上的案例中我們並沒有發現‘‘號於“”號有什麽區別,但是我們來繼續看下面的案例

總結:""這種定義的方式特點是:輸出變量內容時引號變量及命令會經過解析後在輸出

把一個變量命令賦值的方法

例如:我們要查詢我們的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變量的特殊用法

好了,本章就結束了,希望對您有所幫助! 再見~~~

Shell編程之變量(詳解)