一、 什么是變量
變量源于數學,在計算機語言中能儲存計算機結果或能表示值的抽象概念,變量可以由變量名訪問,在指令語言中,變量通常是可變的。Linux是一個多用戶的操作系統。每個用戶登錄系統后,都會有一個專用的運行環境。通常每個用戶默認的環境都是相同的,這個默認環境實際上就是一組環境變量的定義。用戶可以對自己的運行環境進行定制,其方法就是修改相應的系統環境變量。
1. 變量的命令規則
1) 不能使程序中的保留字:例如if, for;
2) 只能使用數字、字母及下劃線,且不能以數字開頭
3) 見名知義
4) 統一命名規則:駝峰命名法
2. 變量分類(根據生效范圍劃分)
本地變量,環境變量,局部變量,位置變量,特殊變量
3. 變量類型
字符
數值:整型、浮點型
a) 強類型:定義變量時必須指定類型、參與運算必須符合類型要求;調用未聲明變量會產生錯誤。
b) 弱類型:無須指定類型,默認均為字符型;參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用
只讀變量:只能聲明,不能修改和刪除
readonly name
declare –r name
4. 算數運算
+, -, *, /, %取模(取余), **(乘方)
實現算術運算:
(1) let var=算術表達式
(2) var=$[算術表達式]
(3) var=$((算術表達式))
(4) var=$(expr arg1 arg2 arg3 …)
(5) declare –i var = 數值
(6) echo ‘算術表達式’ | bc
乘法符號有些場景中需要轉義,如*
5. 增強型賦值:
+=, -=, *=, /=, %=
例如:letsum+=3
自加3后自賦值
自增,自減:
let var+=1
let var++
let var-=1
let var–
二、 本地變量
對當前shell進程有效,出當前shell進程之外的其他進程無效,比如我設定一個本地變量a=1,這個值只在當前用戶當前shell有生命周期意義,如果在shell中又開啟一個子shell或退出shell重新登錄一個shell,那么這個a的變量值就無效了,這個方法的有點就是用戶不能對其他shell或進程設置次變量有效。
使用變量時,如果用“{}”括起來,可以防止shell誤解為變量值,盡管不必一定這樣做,但這確實可用,設定本地變量的格式如下:
name=’value’
name=”root’ 直接使用字符串
name=”$USER 變量引用,將引用$USER這個變量的值作為name的變量值
name=`command`,name=$(command),比如我使用name=`id -un`,取出id這個命令的執行結果來作為name變量的值
變量引用又分為強引用和弱引用,當變量時強引用(單引號)時,其中的變量引用不會被替換為變量值,弱引用(雙引號)時,其中的變量引用會被替換為變量值,就拿杠桿name=$USER來說,如果我加的是雙引號,那么$USER這個變量就會將值賦值給name這個變量,如果是單引號,值將會原樣輸出
顯示已定義的所有變量:set
刪除變量:unset 變量名,當我們執行某個程序完成后,最好將變量的刪除,以釋放內存空間。
三、 環境變量
對當前shell以及子shell都有效,登錄進程稱為父進程,shell中執行的用戶稱為子進程,不像本地變量只用于當前shell,,他能用于所有的子進程,/etc/profile文件中已經設置了一些環境變量。將之放入profile文件意味著每次登錄式這些值都將被初始化。所有的環境變量均為大寫。環境變量應用于用戶進程前,必須使用export命令導出,環境變量與本地變量設置方法相同
export name=’value’
declclare –x name=value
變量引用:$name, ${name}
顯示已定義的環境變量printenv ,env,export命令查看
清楚環境變量:unset 環境變量名稱
bash有許多內建的環境變量:PATH, SHELL, USRE,UID, HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1
四、 局部變量
對當前shell進程中的某段代碼有效,在程序運行期間不是一直存在,而只是在函數執行期間存在,函數的一次調用結束后,變量就會撤銷,其所占的內存也會被收回,比如我在腳本里定義個局部變量,當我執行完腳本之后這個局部變量就會被刪除。
五、 位置變量
$1,$2…來表示,用于讓腳本在執行的過程中調用,通過命令行傳遞參數
六、 特殊變量
$?:上個命令的執行狀態結果,$?返回0??梢栽谌魏蚊罨蚰_本中返回此變量以獲得返回信息?;诖诵畔?,可以在腳本中做更進一步的研究,返回0意味著成功,非0為出現錯誤。
$0:指腳本名本身
$#:傳遞給腳本參數的個數
$*:以一個單字符串顯示所有向腳本傳遞的參數。與位置變量不同,此選項參數可超過9個。
$@:與$ #相同,但是使用時加引號,并在引號中返回每個參數,兩者不加引號表示的意思相同,如果加引號,前者表示的是一個整體,當做一個參數來使用,而后者為多個參數。
$-:顯示shell使用的當前選項,與set命令功能相同
$!:后臺運行的最后一個進程的進程id號
七、 三者之間的差異
本地變量,環境變量,局部變量之間的區別,三者的影響范圍不同,范圍從大到小依次是,環境變量,本地變量,局部變量,而環境也是全局的,對所有用戶都生效,其他兩個,只針對當前用戶有效。
環境變量,傳遞給子進程的變量,遺傳性是環境變量和其他兩者之間的差別,只能單向從父進程傳遞給子進程,不管子進程的環境變量如何變化,都不會影響父進程的環境變量
作業
1、 編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。
顯示主機信息用hostname命令可以實現
ipv4的地址需要配合cut ,grup等文本處理工具
操作系統版本可以查看/etc/centos-release 的文件內容便可查到
內核版本使用uname –r 命令來查詢
cpu,使用lscpu,查詢到一大串訊息,截圖cpu型號即可
內存大小,可以使用命令free 也可以查看/pro/meminfo文件的內容,來查看內存的大小
硬盤的容量可以使用lsblk列出塊設備的信息,也可是用fdisk –l命令來列出硬盤的容量,通過文本工具來截取所需的內容
具體腳本內容如下:
#!/bin/bash
#
Hname=`hostname`
echo "the host name is $Hname"
IP=` ifconfig |grep "inet addr"|cut -d : -f2|cut -d ' ' -f1|head -1`
echo "the ip address is $IP "
Osversion=`cat /etc/centos-release`
echo "the oprating system version is $Osversion"
Kversion=`uname -r`
echo "the kernel version is $Kversion"
Cpu=`cat /proc/cpuinfo |grep ‘model name’ -n |cut -d : -f3|head -1 `
echo -e "the cpu type is $Cpu"
Mem=`cat /proc/meminfo |head -1 |cut -d : -f2`
echo "the memory total is $Mem"
Disk=`fdisk -l|grep "^Disk /dev/sd[a-z]" |cut -d : -f2|cut -d , -f1 `
echo "the disk total is $Disk"
2、 編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中
將/etc/下所有文件和目錄都備份到/root/下以日期命令的文件中,利用cp命令時需要帶上-r遞歸選項,連同目錄一起復制,日滴只需要在腳本中利用命令替換即可
#!/bin/bash
cp -r /etc/ /root/`date +%F%T`
ls /root/`date +%F%T`
3、 編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值
利用df -h 命令查看硬盤分區中空間利用率最大的值,其中要出去光盤的使用率,配合使用文本處理工具來找出空間利用率最大值
#!/bin/bash
#
use=`df -P|grep -v "/dev/sr0"|tr -s ' ' ':'|cut -d : -f5|sort -nr|head -1`
echo “ The disk has use : $use”
4、 編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序
#!/bin/bash
#
Link=`netstat -nt|tr -s ' ' ':'|cut -d : -f4|grep -v "[[:alpha:]]"|sort -rn`
echo –e “thes host is :\n $Link
5、 寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和
利用sed截取/etc/passwd文件中的第10行和20行,利用cut
取出他們的uid保存在變量中,然后計算兩者之和
#!/bin/bash
#
A=`sed -n '10p' /etc/passwd |cut -d : -f3`
B=`sed -n '20p' /etc/passwd |cut -d : -f3`
C=$[$A + $B]
echo $C
6、 寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和
查找文件中的空行,并統計行數保存在一個變量中,以此來計算兩個變量之和
#!/bin/bash
#
A=`grep "^$" /etc/rc.d/rc.sysinit|wc -l`
B=`grep "^$" /etc/fstab |wc -l`
#sum=$(($A+$B ))
sum=$[ $A + $B ]
echo $sum
7、 寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件
列出目錄下的所有文件和目錄通過wc來統計文件的個數
#!/bin/bash
#
A=`ls /etc/|wc -l`
B=`ls /var/ |wc -l`
C=`ls /usr/ |wc -l`
D=$[$A + $B +$C]
echo $D
8、 寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;如果參數個數不小于1,則顯示第一個參數所指向的文件中的空白行數
#!/bin/bash
read -p "please input a filename :" FILE
[ $# -lt 1 ] && read -p "please input filename again :" FILE
sum=`grep "^$" $FILE |wc -l `
echo $sum
9、 寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”
#!/bin/bash
#
[ $# -lt 1 ] && read -p "please input a ipv4 address:" IP
echo $IP | grep -Eo "(\<([0-9]|1[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>)\.){3}(\<[0-9]|1[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>)"
[ $? -eq 0 ] && ping -c1 -w1 $IP &>/dev/null && echo "the ip is up,can be access " || exit 3
10、判斷硬盤的每個分區空間和inode的利用率是否大于80,如果是,發郵件通知root磁盤滿
#!/bin/bash
#
#device
ddev=`df -h |grep "sd[a-z]"|cut -d ' ' -f1`
duse=`df -P|grep -v "/dev/sr0"|grep -v "Filesystem"|tr -s ' ' ':'|cut -d : -f5|sort -nr |head -1 |cut -d % -f1`
#the inode use percent
Iuse=`df -Pi|grep -v "/dev/sr0"|grep -v "Filesystem"|tr -s ' ' ':'|cut -d : -f5|sort -nr |head -1|cut -d % -f1 `
[ "$duse" -ge 80 ] && echo "" |mail -s "the disk space is too samll" root || [ "$Iuse" -ge 30 ] && echo "the inod number is too samll" |mail -s "dsik About to run out" root ||exit 3
11、 指定文件做為參數,判斷文件是否為.sh后綴,如果是,添加x權限
#!/bin/bash
#
[ $# -lt 1 ] && read -p " please input a filename :" File
[ ! -e $File -a ! -f $File ] && echo "please input a true file " && exit 3
echo $File |grep -q ".*\.sh" && chmod +x $File ; echo "the file add chmod finshed "|| echo "this i not a sh file"
12、判斷輸入的IP是否為合法IP
#!/bin/bash
#
read -p " please input a ip address: " IP
[ -z $IP ] && read –p please input a ip address :” IP
A=` echo $IP |grep -Eo "(\<([0-9]|1[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>)\.){3}(\<[0-9]|1[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>)"|wc -l`
[ $A -gt 0 ] && echo " the ip is legal" || echo " the ip is not legal"
13、計算1+2+3+…+100
#!/bin/bash
#
sum=`echo {1..100}|tr ' ' '+' |bc `
echo "The sum is $sum."
14、輸入起始值A和最后值B,計算從A+(A+1)…+(B-1)+B的總和
#!/bin/bash
#
read -p "please input a number :" A
read -p "please input a number :" B
[ $A -ge $B ] && echo "sum is `seq -s+ $B $A |bc `" || echo "sum is `seq -s+ $A $B |bc`"
原創文章,作者:fszxxxks,如若轉載,請注明出處:http://www.www58058.com/33721