變量
變量:能儲存計算結果或能表示值抽象概念,其指向的內存空間中一段地址。
變量賦值:name=value
溢出:字符超過定義內存中間大小
變量類型:數據類型,存儲的格式,參與的運算
編程語言:弱類型編程語言shell
變量聲明:無需聲明數據類型
不以數字開頭,字符,數字,下劃線,符號組合而成,不能使用系統保留字符(if,esle)如
apple_sum,appleSum,user_name,userN等等ame
變量賦值,用‘=’
apple_sum=10, appleSum=10,等等
user_name=xiong ,userName=xiong,等等
變量引用:$變量 或者 ${變量}
echo $apple_sum $user_name $appleSum
bash變量類型 注意:數字不加引號,其他都加雙引號,在awk中正好相反,單引號表示解析,雙引號表示不解析
1.本地變量:shell程序定義的變量,作用域僅限于當前進程本身,sshd終端開啟的進程
[root@localhost ~]# pstree
2.環境變量:linux定義的特殊變量,作用域為當前shell進程及其子進程,如:USER,UID,SHELL,HISTSIZE,等等
環境變量在/etc/profile, /etc/profile.d , /etc/bashrc , 用戶目錄下.bash_profile,.bashrc等中定義
環境變量聲明種類: 引用為:${變量},提醒中變量多是大寫,我們在寫shell盡量不要大寫
1. export name=value 或者 name=value;export name
2.declare -x name=value 或者 declare -x; x=value
可以用:export,printenv,env,delclare -x查看系統環境變量,撤銷環境變量用:unset 變量
3.只讀變量:
declare -r 變量,readonly 變量 ,只讀無法重新賦值,不支持撤銷,隨shell進程終止而終止。
4.命令變量,用反引號(` =shift+波浪號)
1種:name=`echo xiong` 2種:name=$(echo xiong)
5.局部變量:作用域僅為程序的某個片(函數上下文)
用local定義,也可不用
6.參數變量:當執行的shell進程傳遞的參數
7.特殊變量 shell內置的有特殊功用的變量
$0:獲取當前執行shell腳本的文件名
$n:獲取當前執行shell腳本的第n個參數,n=1,2,3,4…..9,當n>9時,用${10}引用
$#獲取當前執行shell腳本參數總個數
$*所有參數
$@所有參數
$?獲取當前shell執行狀態,0表示成功,1-255表示失敗,2權限不夠,126不能執行,127未找到名利
$$獲取當前shell執行的pid號
$!獲取上個shell執行的pid號
${#變量名} 獲取shell變量字符長度, 返回變量字符長度 ${#xiong}, 或用 echo $變量 | wc -m,返回變量字符長度
${變量:位置數}從位置數后截取字符串,maoxiong=maoxiong, echo ${maoxiong:2} 將顯示:oxiong
${變量:位置起始a,位置結束b} 從變量第a位置,截取到b位置: ${maoxiong:2:2} echo ${maoxiong} | cut -c 3-4
${變量#刪除字符串}刪除變量指定字符串 ,maoxiong=l am a boy;${maoxiong#l am} 結果顯示a boy
${變量##刪除字符串}刪除變量指定字符串 ,maoxiong=l am a boy;${maoxiong##l am a } 結果顯示boy
${變量%刪除字符串,從結尾處刪除} maoxiong=l am a boy,${maoxiong%boy} ,結果顯示l am a old
${變量/需要替換的字符/替換的字符} ${maoxiong/l am /you are},結果顯示為you are boy
${變量/#需要替換的字符/替換的字符}從開頭開始匹配 ${maoxiong/#l am /you are},結果顯示為you are boy
變量=${man:-word}如果變量名存在,且非null,則返回變量的值。否則,返回word字符串。
用途:如果變量未定義,則返回默認值。范例:
${value:-word},如果value未定義,則表達式值為word
result=${man:-unset}如果man沒值,則result值為unset。
變量=${man:=word}如果變量名存在且非null,則返回變量值。否則,設置這個變量值為word,并返回其值。
用途:如果變量未定義,則設置變量為默認值,并返回默認值。
result=${man:=set} 如果man沒有值,則將unset值賦給man,在將值賦給result
變量=${man:?"not defined}如果變量名存在且非null,則返回變量的值。否則顯示變量名:message,并退出當前的命令或者腳本。用途:用于捕捉由于變量未定義而導致的錯誤,并退出程序
result=${man:?word} 如變量man存在,則返回word,否則返回空
變量=${value:+word}如果變量名存在且非null,則返回word,否則返回ull
用途:測試變量是否存在。
范例:${value:+word},如果value已經定義,則返回word(也就是真)
bash特性之多shell命令執行
命令 1;命令2;命令3;。。。。
set 查看設置的變量
set 變量名=value 設置變量
unset 變量 撤銷變量,服務器的資源有限,在程序執行完成后,變量或者數據庫連接資源必須關閉。
注意shell腳本是運行一個shell進程實現的
bash的配置文件
兩類:
profile類:為交互式登錄的shell進程提供配置 交互式如:su – root
bashrc類:為非交互式登錄的shell進程提供配置 非交互式:1. su root
2.圖形界面打開的終端 3.運行的腳本等
profile類:
全局:對所有用戶都生效
/etc/profile /etc/profile.d/*.sh(自己自己創建shell腳本)
用戶個人的:僅對個人有效
~/.bashprofile
功用:
1.用于定義環境變量 2.運行命令或腳本
bashrc
全局:對所有用戶都生效
/etc/bashrc
用戶個人的:僅對個人有效
~/.bashrc
功用:
1.定義本地變量 2.定義命令別名
注意:僅管理員可修改全局配置文件
配置文件讀取順序
交互是登錄shell進程:
/etc/profile–>/etc/profile.d/*–>~/.bash_profile—>~/.bashrc—>/etc/bashrc
非交互式登錄shell進程:
~/.bahrc–>/etc/bashrc–> /etc/profile.d/*
命令行中定義的特性,例如變量和別人作用域為當前shell進程的生命周期
配置文件定義的特性,只對隨后新啟動的shell進程有效
讓配置文件加載方法
(1)重新登錄系統
(2)通過bash執行: .配置文件 重讀配置文件
(3)讓shell進程重讀配置文件: source 配置文件
實例:vim /etc/profile.d/xiong.sh
內容為:echo welcome to xiong linux
source /etc/profile.d/xiong.sh
hell腳本編程大致分兩類,根據運行方式:
編譯運行:源代碼–>編譯器轉換為程序文件,然后才能運行 tar -zxvf test.tar.gz make&&make install
解釋運行:源代碼–>運行時啟動解釋器,由解釋器邊解釋變運行
程序執行過程:
過程式: 順序執行,選擇執行,循環執行
對象式:首先定義對象,在用順序執行,選擇執行,循環執行
shell腳本規范: #為注釋符
shell腳本第一行要寫shell腳本的解釋器 #!/bin/bash 指定shell腳本的解釋器
第二行:#shell編寫者,編寫時間,聯系方式
第三行#注釋shell腳本作用等等
運行shell腳本
1.sh shell.sh 不需要執行權限 2. ./shell.sh 腳本shell.sh必須要有執行權限
3.bash shell.sh 腳本shell.sh必須要有執行權限
4.sh -x 腳本 或者bash -x 腳本 ,顯示腳本執行的過程,便于用戶調試程序bug
time命令 顯示shell程序執行的時間,用測試程序反應時間
邏輯運算
true為真,用1表示。 false為假,用0表示
邏輯與: 邏輯或: 邏輯非:
1與1=1 1或1=1 !1=0
1與0=0 1或0=1 !0=1
0與1=0 0或1=1
0與0=0 0或0=0
短路運算:
短路運算: 短路或運算: 短路異或:^
第一個為0,結果必定為0 第一個為1,結果必定為1; 異或的兩個值,相同為假,不同為真
第一個為1,第二個必須要參與運算; 第一個為0,第二個必須要參與運算;
聚集命令的方法:
復合式,用分號隔開,如 date; who | wc -l
命令會一個接一個地運行
子shell:(date; who | wc -l ) >>/tmp/trace 所有的輸出都被發送給單個STDOUT和STDERR
退出狀態碼
進程使用退出狀態來報告進程的執行成功或者失敗
0 代表成功,1-255代表失敗
$? 變量保存最近的命令退出狀態
示例:
自定義退出狀態碼,用于捕捉摸個進程的執行狀態
exit [n]:自定義退出狀態碼;
注意: (1)腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字
(2)如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼
示例: 條件測試:
判斷某需求是否滿足,需要由測試機制來實現, 專用的測試表達式需要由測試命令輔助完成測試過程;
評估布爾聲明,以便用在條件性執行中
如果條件為真,則返回0 否則則返回1
測試命令模型:
test 表達式 長格式 如: test $a -eq $b
[ 表達式 ] 短格式 如: [ $a -eq $b ]
[[ 表達式 ]] 如: [[ $a -eq $b ]]
注意:表達式前后必須有空白字符
條件性的執行操作符
根據退出狀態而定,命令可以有條件地運行
&& 代表條件性的AND THEN 實例: grep -q batman /etc/passwd || echo "no such batman"
|| 代表條件性的OR ELSE 實例:ping 10.1.0.2 -c 4 &> /dev/null && echo "10.1.0.1 is up" || echo "10.1.0.1 is down"
組合測試條件
第一種方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
第二種方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必須使用測試命令進行; [ $USER == "root" -a -e "/etc/issue" ] && sed -n "/^#[[:space:]][[:alnum:]]\+/p" /etc/fstab
bash數值計算符(用于shell數值變量計算) 注意linux對于有小數計算時,需要用bc命令
1.基本運算符
+(加) -(減) *(乘) /(除)
%(取余或者叫做取模,如:4%3=1) **( 乘方)
2.增強運算符
+= 如: a+=2等于a=a+2
-= 如: a-=2等于a=a-2
*= 如 : a*=2等于a=a*2
/= 如 : a/=2等于a=a/2
%= 如: a%/2等于a=a%2
a++ 等于a,下一次則是a+1 a–等于a,下一次則是a-1++a –a 記憶方法:變量再前,先輸出變量值,變量再后,就是先運算后再輸出變量制的值。
3.數值運算
(1) let var=算術表達式 (2) var =$[算術表達式] (3) var =$((算術表達式))
(4)var=$(expr arg1+arg2) (5)declare -i var=數值 (6) echo '算術表達式' | bc
4.數值測試:
測試格式: (1) test 表達式 (2) [ 表達式 ] 注意有空格 (3) [[ 表達式 ]] 注意空格
數值測試類型 ,執行狀態:0位真,1為假
(1) -eq 等于 [ a -eq b ] , 如果a=b,則執行狀態為真 ,否則執行狀態為假
(2) -ne 不等于 [ a -ne b ] , 如果a!=b,則執行狀態為真 ,否則執行狀態為假
(3) -gt 大于 [ a -gt b ], 如果a>b,則執行狀態為真,否則執行狀態為假
(4) -ge 大于等于 [ a -ge b ] ,如果a>=b,則執行狀態為真,否則執行狀態為假
(5) -lt 小于 [ a -lt b ] ,如果 a<b,則執行狀態為真,否則執行狀態為假
(6) -le 小于等于 [ a -le b ] ,如果a<=b,則執行狀態為真,否則為假
字符串測試 注意:1.字符串用> ,<符號比較是需要加轉義字符'\',不然系統為認為是重定向等.2字符變量最好用${變量}或者"$變量"
(1) == 或 = : 測試字符串是否相等,如 a="xiong",b="xiong" ;[ $a == $b ] ,如果a等于b字符串,則執行狀態為真,否則為假
(2) > 字符串1ascii碼是否大于字符串2ascii碼 ,如 [ a > b ] ,如果a的ascii碼大于b的ascii碼,則執行狀態為真,否則為假
(3) < 字符串1ascii碼是否小于字符串2ascii碼 ,如 [ a < b ] ,如果a的ascii碼小于b的ascii碼,則執行狀態為真,否則為假
(4) != 測試字符串不相等,[ $a != $b ] ,如果a字符串不等于b,則執行狀態為真,否則為假
(5) =~ 左側字符串是否能夠被右側的pattern所匹配;注意,注意:此表達式一般用于[[ ]]中
(6) -z string : 字符串為空,則為真,否則為假
(7) -n string :字符串不空,則為真,否則為假
文件測試
存在性測試
-a FILE:同-e
-e FILE: 文件存在性測試,存在為真,否則為假;
存在性及類別測試
-b FILE:是否存在且為塊設備文件;
-c FILE:是否存在且為字符設備文件;
-d FILE:是否存在且為目錄文件;
-f FILE:是否存在且為普通文件;
-h FILE 或-L FILE:存在且為符號鏈接文件;
-p FILE:是否存在且為命名管道文件;
-S FILE:是否存在且為套接字文件;
文件權限測試:
-r FILE:是否存在且可讀
-w FILE: 是否存在且可寫
-x FILE: 是否存在且可執行
-g FILE:是否存在且擁有sgid權限;
-u FILE:是否存在且擁有suid權限;
-k FILE:是否存在且擁有sticky權限;
文件屬組測試
-t fd: fd表示文件描述符是否已經打開且與某終端相關
-N FILE:文件自動上一次被讀取之后是否被修改過
-O FILE:當前有效用戶是否為文件屬主
-G FILE:當前有效用戶是否為文件屬組
文件大小測試:
文件是否為空測試
-s FILE: 是否存在且非空;
文件對比測試,也叫雙目測試:
FILE1 -ef FILE2: FILE1與FILE2是否指向同一個設備上的相同inode
FILE1 -nt FILE2: FILE1是否新于FILE2;
FILE1 -ot FILE2: FILE1是否舊于FILE2;
20160810作業
一、腳本
1、編寫腳本/root/bin/,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。
#!/bin/bash
hname=`hostname`
ipaddr=`ifconfig | sed -n '2p' | cut -d ':' -f 2 | cut -d ' ' -f 1`
osversion=`cat /etc/issue | head -1`
linuxKernel=`uname -r`
linuxCup=`lscpu | grep 'Model[^:].*' | tr -s ' '| cut -d : -f 2 | tr -s ' '`
linuxhard=`lsblk | sed -n 3p | grep -o "\<[0-9]\+[G]\>"`
linuxme1=`free -h | grep "^[[:alpha:]].*" | tr -s ' ' | cut -d ' ' -f 1,2 | tr '\n' ' ' | cut -d ' ' -f2`
linuxme2=`free -h | grep "^[[:alpha:]].*" | tr -s ' ' | cut -d ' ' -f 1,2 | tr '\n' ' ' | cut -d ' ' -f4`
echo "主機名:$hname 主機IP:$ipaddr"
echo "系統版本:$osversion 系統內核版本:$linuxKernel"
echo "cpu型號:$linuxCup 硬盤大小:$linuxhard"
echo "內存:$linuxme1 共享內存:$linuxme2"
2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中
實現自動換備份
下面shell腳本是以每分鐘備份的
#!/bin/bash
#author QQ:111111111
backTime=`date +%F-%M`
cronDir=/var/spool/cron/root
cp -r /etc/ /root/etc$backTime
#通過echo輸入crontab任務,可見自動執行創建任務,但是系統可能有警告
if [ -e $cronDir ];then
#task=`grep "backup.sh" $cronDir | cut -d ' ' -f 7`
task=`grep "backup" $cronDir | wc -l`
if [ $task -eq 0 ];then
echo "*/1 * * * * /bin/bash /root/backup.sh" >> $cronDir
echo "backup任務已經創建。"
else
echo "backup已經存在"
fi
fi
3、編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值
#!/bin/bash
#author QQ:111111111
dUser=`df -h | grep "^\/" | tr -s ' ' | tr -d '%' | sort -t ' ' -k 5nr | head -n 1 |cut -d ' ' -f 5`
diskno=`df -h | grep "^\/" | tr -s ' ' | tr -d '%' | sort -t ' ' -k 5nr | head -n 1 |cut -d ' ' -f 6`
echo "$diskno: $dUser%"
4、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序
#!/bin/bash 系統壞了,寫的shell沒了,趕作業弄個簡單版
#author QQ:111111111
netstat -tan | grep "ESTABLISHED" | awk '{print $5}'| cut -d: -f1|sort|uniq -c
5、寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的
#!/bin/bash
#author QQ:111111111
var1=`cat /etc/passwd | sed -n "10p"|cut -d: -f3`
var2=`cat /etc/passwd | sed -n "20p"|cut -d: -f3`
let var3=var1+var2
echo "5、第10個用戶和第20用戶的ID之和:$var3"
6、寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和
#!/bin/bash
#author QQ:111111111
file1=`grep "^$" $1 |wc -l`
file2=`grep "^$" $2 |wc -l`
file3=$[file1+file2]
echo "$1,$2兩個文件中所有空白行之和:$file3"
7、寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件
#!/bin/bash
#author QQ:111111111
dirNum=`ls -l /etc/ /var/ /usr/ | cut -c1|sort | uniq -c | grep '-'| tr -s ' '| tr -d '-'
`
fileNum=`ls -l /etc/ /var/ /usr/ | cut -c1|sort | uniq -c | grep 'd'| tr -s ' '| tr -d 'd'
`
echo "文件有:$fileNum,目錄有:$dirNum"
8、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;
如果參數個數不小于1,則顯示第一個參數所指向的文件中的空白行數
#!/bin/bash
#author:maoxiong QQ:111111111
#verson:1.0 date:2016-08
#illustrate:Comparison numbe
[[ $# -lt 1 ]] && echo "輸入參數小于 1" || (echo "文件中空白行為:";grep -c '^[[:space:]]*$' $1)
9、寫一個腳本/root/bin/,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”
;如果不可ping通,則提示用戶“該IP地址不可訪問”
#!/bin/bash
#author QQ:111111111
read -p "請輸入需要檢查的ip地址:" ipaddr
ping $ipaddr -c 2 &> /dev/null && echo "該$ipaddr地址可以訪問"||echo "該$ipaddr地址不可訪問"
10、判斷硬盤的每個分區空間和inode的利用率是否大于80,如果是,發郵件通知root磁盤滿
11、指定文件做為參數,判斷文件是否為.sh后綴,如果是,添加x權限
#!/bin/bash
#author QQ:111111111
read -p "請輸入文件:" file
echo $file | grep -o ".sh$" &> /dev/null
num=0
[ $statusNum -eq $num ] && (chmod a+x $file ;echo "$file文件存在") || echo "$file文件不存在"
13、計算1+2+3+…+100
#!/bin/bash
#author QQ:111111111
read -p "請輸入連續累加起始值:" var1
read -p "請輸入連續累加結束值:" var2
num1=$var1
num2=$var2
let num3=(num1+num2)*num2/2
echo "$num1至$num2累加總合是:$num3"
14、輸入起始值A和最后值B,A大于B,計算從A+(A+1)…+(B-1)+B的總和
#!/bin/bash
#author QQ:111111111
read -p "請輸入A值:" var1
read -p "請輸入B值:" var2
a=$var1
b=$var2
[ $a -lt $b ] && echo "A+..+B=`seq -s+ $a $b | bc`" || echo "A>B,請重新輸入"
原創文章,作者:maoxiong,如若轉載,請注明出處:http://www.www58058.com/34529
總結的很詳細,排版也很工整,態度公正,望以后的博客能按時提交。