一、簡述
變量是指內存空間的命名,指向內存中一個或一組地址。bash shell中的變量屬于弱類型變量,使用變量無需聲明、不需要指定類型,默認為字符型變量。
二、變量命名、賦值、引用
(1)命名規則:
1.只能使用字母,數字,下劃線;并且不能使用數字開頭。
2.不能使用bash關鍵字,可用help命令查看,例如:if,for。
3.見名知意,變量命名人性化,好的命名有助于提升腳步易讀性。
(2)變量賦值,引用
變量使用等號來賦值;
引用變量時,在變量名前加$,形式有$var,${var},"$var"。像$var這種簡便方式容易和上下文混淆變量名
1.當給變量名賦值字符串時,字符串當中不含空格可以不使用引號
~]$ name=tom #等號兩邊不能有空格出現 ~]$ title="What is Linux?" #字符串中含有空格,使用引號括起 ~]$ title='What is Linux?'
2.變量賦值引用變量時,只能使用弱引用"",使用強引用''不會引用變量值
[root@centos7 ~]$ path="/home/$USER" [root@centos7 ~]$ echo $path /home/root [root@centos7 ~]$ path='/home/$USER' #使用單引號只會原樣賦值 [root@centos7 ~]$ echo $path /home/$USER
3.變量接收命令結果,使用$()或者反引號` `
[root@centos7 ~]$ userid=$(id -u root) [root@centos7 ~]$ echo $userid 0 [root@centos7 ~]$ username=`whoami` [root@centos7 ~]$ echo $username root
三、變量分類
按作用范圍可劃分為:
-
局部變量
生效范圍是當前shell中某代碼片段,通常指函數中的變量
-
本地變量
生效范圍是當前shell進程,及當前shell中(command1;command2;)形式的subshell
-
全局變量
生效范圍是當前shell進程,及其子進程
[root@centos7 ~]$ name=tom;echo $name #定義本地變量name tom [root@centos7 ~]$ (echo $name) #()形式的subshell可以取得name變量值 tom [root@centos7 ~]$ (name=bob;echo $name;) bob [root@centos7 ~]$ echo $name #重新定義的變量不能傳遞出來 tom
全局變量
全局變量的聲明方式為:
export variable 或者 declare -x variable
[root@centos7 ~]$ cat test.sh #新建一個腳本,看本地變量name是否生效 #!/bin/bash echo there is subshell echo name is $name [root@centos7 ~]$ ./test.sh there is subshell name is #name變量值沒有傳遞進來 [root@centos7 ~]# export name #將name聲明為環境變量 [root@centos7 ~]# ./test.sh there is subshell name is tom #name變量值此時生效
查看當前shell環境變量命令為
bash$ env;printenv;declare;
撤銷變量命令
bash$ unset variable
定義的環境變量會隨著shell退出而失效,可將export variable=value 寫入~/.bashrc
四、位置變量,特殊變量
位置變量
$1,$2,$3…用于腳本中,獲取通過命令行傳遞給它的參數
$# 記錄命令行參數的個數
$*,$@ 表示所有的參數。當引用所用參數使用""引起時,二者是有區別的,$*將所有參數表示為一個整體,
而$@將所有參數獨立表示
[root@centos7 ~]$ cat positionVar.sh #測試位置參數腳本 #!/bin/bash echo 1st args is $1 echo 2sec args is $2 echo 3rd args is $3 echo args number is $# echo all args are $* echo all args are $@ [root@centos7 ~]$ ./positionVar.sh dog cat fish #傳遞三個參數:dog,cat,fish 1st args is dog 2sec args is cat 3rd args is fish args number is 3 all args are dog cat fish all args are dog cat fish
測試$*,$@的區別
[root@centos7 ~]# cat positionAll.sh #新建腳本 #!/bin/bash echo test '$*'------------ ./positionVar.sh "$*" echo test '$@'------------ ./positionVar.sh "$@" [root@centos7 ~]# ./positionAll.sh dog cat fish #測試,傳遞三個參數 test $*------------ 1st args is dog cat fish # $*將多個參數整體傳遞進來 2sec args is 3rd args is args number is 1 all args are dog cat fish all args are dog cat fish test $@------------ 1st args is dog # $@將多個參數單獨傳遞進來 2sec args is cat 3rd args is fish args number is 3 all args are dog cat fish all args are dog cat fish
特殊變量
1.$0 表示執行命令本身
[root@centos7 ~]# ./test.sh the script is ./test.sh [root@centos7 ~]# /root/test.sh the script is /root/test.sh
2.$? 表示命令執行狀態碼;腳本的狀態碼為最后一條命令的狀態碼
0 表示執行成功
1-255 表示執行失敗
[root@centos7 ~]# ll -d /root dr-xr-x---. 16 root root 4096 Aug 13 11:34 /root [root@centos7 ~]# echo $? 0 #成功 [root@centos7 ~]# ll -d /roots ls: cannot access /roots: No such file or directory [root@centos7 ~]# echo $? 2 #失敗 [root@centos7 ~]# lls -d /root bash: lls: command not found... Similar command is: 'ls' [root@centos7 ~]# echo $? 127 #失敗
五、課后作業
1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。
#!/bin/bash echo "hostname:`hostname`" echo -e "IPv4:\n`ifconfig|sed -nr 's/inet (([0-9]{1,3}\.){3}[0-9]{1,3})(.*)/\1/p'`" echo "OS:`cat /etc/centos-release`" echo "Kernel:`uname -r`" echo "CPU:`lscpu|sed -nr s/'Model name:[[:space:]]+\<//p'`" echo "Memory:`free -m |grep Mem|tr -s ' '|cut -d' ' -f2`M" echo "Disk:`lsblk|grep disk|tr -s ' '|cut -d' ' -f4`"
2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中
#!/bin/bash echo "backup dir /etc" cp -a /etc /root/etc`date +%F` echo "backup finish `date +%F`"
3、編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值
#!/bin/bash echo "the max ratio of partiton used is:`df |grep /dev/sd|cut -c 45-46|sort -n|tail -1`%"
4、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序
#!/bin/bash echo "links is :`netstat -tn|grep tcp|tr -s ' '|cut -d: -f2|cut -d' ' -f2|sort|uniq -c|sort -nr`"
5、寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和
6、寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和
#!/bin/bash num1=`grep '^$' $1 |wc -l` num2=`grep '^$' $2 |wc -l` echo "sumspace is :$[num1+num2]"
7、寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件
#!/bin/bash num1=`(ls $1;ls $2;ls $3)|wc -l` echo "files total :$num1"
8、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;如果參數個數不小于1,則顯示第一個參數所指向的文件中的空白行數
#!/bin/bash read -p "please input at least one args :" filepath [[ -n $filepath ]]&&echo "blank lines number:`grep -c '^$' $filepath`"||echo "at least one args"
9、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”
#!/bin/bash read -p "please input a IPv4:" ipaddr ping -W1 -c1 $ipaddr &>/dev/null&&echo "the IP is reachble"||echo "the IP is unreachble"
10、判斷硬盤的每個分區空間和inode的利用率是否大于80,如果是,發郵件通知root磁盤滿
#!/bin/bash diskmax=`df|grep /dev/sd|cut -c 45-46|sort -n|tail -1` inodemax=`df -i|grep /dev/sd|cut -c 43-44|sort -n|tail -1` [[ $diskmax -gt 80 || $inodemax -gt 80 ]]&&mail -s 'disk warning' root /etc/issue||echo "disk space is ok"
11、指定文件做為參數,判斷文件是否為.sh后綴,如果是,添加x權限
#!/bin/bash [ ! -f $1 ]&&echo no such file or not a common file&&exit [[ $1 =~ .*\.sh$ ]]&&chmod +x $1&&echo chmod +x ok!||echo this is not a shellscript
12、判斷輸入的IP是否為合法IP
#!/bin/bash read -p "input a IP:" ipaddr echo $ipaddr |egrep -q '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$' &&echo "IP is correct"||echo "IP is illegal"
13、計算1+2+3+…+100
$ seq s + 1 100
14、輸入起始值A和最后值B,計算從A+(A+1)…+(B-1)+B的總和
#!/bin/bash read -p "input a start number:" startnum && grep '^[0-9]+$' $startnum &>/dev/null||echo not a number&&exit read -p "input a end number:" endnum &&grep '^[0-9]+$' $endnum ||(echo not a number&&exit) [[ $startnum -ge $endnum ]]&&echo start number greater than end number,illegal||echo sum from start number to end number is:`seq -s + $startnum $endnum|bc`
原創文章,作者:cutemsyu,如若轉載,請注明出處:http://www.www58058.com/34273
總結的很好,并且通過實驗驗證了自己的想法,這對自己理解變量來說,是一個更好的理解方式。