一狸臣、基礎(chǔ)知識
編程語言有低級語言和高級語言兩類莹桅。
高級語言也有編譯型和解釋型的區(qū)分,編譯型語言有C,C++,jave烛亦;解釋型語言有shell统翩,perl,python
shell腳本是一種包含聲明或命令此洲,并符合一定格式的文本文件
shell作為一種過程式解釋型的編程語言,它的基本組織結(jié)構(gòu)有:
數(shù)據(jù)存儲:變量委粉、數(shù)組
表達式
語句:if while case
shell腳本的格式有:
#!SHEBANG
CONFIGURATION_VARIABLES
FUNCTION_DEFINITIONS
MAIN_CODE
shell腳本格式要求首行必須是shebang機制 ,shebang也是指明文件調(diào)用的解釋器類型
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
運行腳本:
給予執(zhí)行權(quán)限呜师,通過具體的文件路徑指明文件執(zhí)行。
直接運行解釋器贾节,將腳本作為解釋器程序的參數(shù)運行汁汗。
二、變量: 命名的存儲空間
數(shù)據(jù)的存儲方式:
字符:
數(shù)值:整型,浮點型
變量類型
作用:
1栗涂、定義數(shù)據(jù)存儲格式
2知牌、定義參與的運算
3、表示的數(shù)據(jù)范圍
類型:
字符
數(shù)值:整型斤程,浮點數(shù)
編程語言的變量又有強類型和弱類型的區(qū)分
強類型:jave角寸,C++
變量不經(jīng)過強制轉(zhuǎn)換菩混,它永遠是這個數(shù)據(jù)類型,不允許隱式的類型轉(zhuǎn)換扁藕,故需要定義數(shù)據(jù)類型
弱類型:bash
變量會有隱式轉(zhuǎn)換沮峡,故不需要指定數(shù)據(jù)類型,所有要存儲的數(shù)據(jù)都當(dāng)做字符進行亿柑,不支持浮點數(shù)
三邢疙、邏輯運算
與:
1 && 1 = 1
1 && 0 = 0
0 && 1 = 0
0 && 0 = 0
或:
1 || 1 = 1
1 || 0 = 1
0 || 1 = 1
0 || 0 = 0
非:
!1 = 0
!0 = 1
異或:相同為假,不同為真
短路運算:
短路與:
第一個為0望薄,結(jié)果必為0
第二個為1疟游,第二個必須要參與運算
短路或:
第一個為1,結(jié)果必為1
第一個為0痕支,第二個必須參與運算
四颁虐、bash中的變量的種類
根據(jù)變量的生效范圍為標(biāo)準(zhǔn):
本地變量:生效范圍為當(dāng)前shell進程,對當(dāng)前shell之外的其他的shell進程無效采转,包括當(dāng)前shell的子shell進程均無效聪廉;
環(huán)境變量:生效范圍為當(dāng)前shell進程及其子進程;
局部變量:生效范圍為當(dāng)前shell進程中某代碼片段(通常指函數(shù))故慈;
位置變量:$1,$2,...來表示板熊,用于讓腳本在腳本代碼中調(diào)用通過命令行傳遞給它的參數(shù);
特殊變量:$?,$0,$*,$@,$#,$$
本地變量:
變量賦值:name=“value”
可以使用單引號:
value:
(1)可以是直接賦值:name=“filename”
(2)變量引用:name=“$username”
(3)命令引用:name=`COMMAND`,name=$(COMMAND)
變量引用:$(name),$name
"":弱引用察绷,其中的變量引用會被替換為變量值干签;
'':強引用,其中的變量引用不會被替換為變量值拆撼,而保持原字符串容劳;
顯示已定義的所有變量:
set
撤銷變量:
unset name
環(huán)境變量:
變量聲明、賦值
export name=VALUE
declare -x name=VALUE
變量引用:$name,$(name)
顯示所有環(huán)境變量:
export
env
printenv
撤銷變量:
unset name
bash中有很多內(nèi)置的環(huán)境變量闸度,PATH,SHELL,UID,HISTSIZE,PWD,OLD,HISTFILE,PS1
變量命名法則:
1竭贩、不能使用程序中的保留字,如if莺禁、for
2留量、只能使用數(shù)字、字母及下劃線哟冬,且不能以數(shù)字開頭
3楼熄、最好見名知義
只讀變量:
設(shè)置只讀變量:
readonly name
declare -r name
查看只讀變量:
readonly -p
位置變量:
在腳本代碼中調(diào)用通過命令行傳遞給腳本的參數(shù):
$1,$2,....:對應(yīng)調(diào)用第1,第2....個參數(shù)
shift [n] 調(diào)換位置浩峡,n不能大于參數(shù)的個數(shù)
$0:調(diào)用命名本身
$*:傳遞給腳本的所有參數(shù)可岂,將所有參數(shù)作為一個整體字符傳遞
$@:傳遞給腳本的所有參數(shù),每一個參數(shù)獨立傳遞翰灾,與$*只有在使用“”引起來時才有區(qū)別
$#:傳遞給腳本的參數(shù)個數(shù)
五缕粹、bash的配置文件
按生效范圍劃分:存在兩類
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
個人配置:
~/.bash_profile
~/.bashrc
按功能劃分:存在兩類
profile類:為交互式登錄的shell提供配置
全局:/etc/profile,/etc/profile.d/*.sh
個人:~/.bash_profile
功用:
(1)用于定義環(huán)境變量
(2)運行命令和腳本
bashrc類:為非交互式登錄的shell提供配置
全局:/etc/bashrc
個人:~/.bashrc
功用:
(1)定義命令別名
(2)定義本地變量
shell登錄:
交互式登錄:
直接通過終端輸入賬號密碼稚茅;
使用“su -UserName”或“su -l UserName”切換的用戶
讀取文件的順序:
/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登錄:
su UserName
圖形界面下打開終端
執(zhí)行腳本
文件讀取順序:
~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
編輯配置文件定義的新配置的生效方式:
(1)重新啟動shell進程
(2)使用source或.命令進程
六、bash中進行算數(shù)運算
+致开,-峰锁,*,/双戳,%虹蒋,...
實現(xiàn)算數(shù)運算:
(1)let var=算數(shù)表達式
sum1=3;sum2=4飒货;let sum=$sum1+sum2
(2)var=$(算術(shù)表達式)
(3)var=$((算術(shù)表達式))
(4)var=$(expr arg1 arg2 arg3...)
sum=$(expr $num1 \* $num2)
*在某些場景下需要轉(zhuǎn)義
bash有內(nèi)置的隨機數(shù)生成器:$RANDOM
echo $[$RANDOM%60] 對60取模魄衅,即生成0-59之間的某個數(shù)
echo $[$RANDOM%60+1] 取1-60之間的某數(shù)
增強型賦值:
+=,-=塘辅,*=晃虫,/=,%=
count+=1 <==> count=count+1
自增扣墩,自減:
let var+=1 <==> let var++
let var-=1 <==> let var--
練習(xí):
1哲银、編寫腳本sumid.sh,計算/etc/passwd文件中的第10個用戶和第20個用戶的id之和
#! /bin/bash
user10="head -n $2 $1 | tail -n 1|cut -d: -f3
"
user20="head -n $3 $1 | tail -n 1|cut -d: -f3
"
let sum=$user10+$user20
echo "user id sum is $sum"
2呻惕、編寫腳本/sumspace.sh荆责,傳遞兩個文件路徑作為參數(shù)給腳本,計算這兩個文件中所有空白行之和
#!/bin/bash
spaceline1=grep "^[[:space:]]*$" $1 | wc -l
spaceline2=grep "^[[:space:]]*$" $2 | wc -l
echo "The sum of space line:$[spaceline1+spaceline2]"
3亚脆、當(dāng)執(zhí)行這個腳本時會自動創(chuàng)建模板腳本文件做院,若腳本后沒有跟參數(shù)則提示用戶輸入生成的腳本文件名,若參數(shù)大于1個濒持,則提示參數(shù)錯誤并退出腳本
#!/bin/bash
[ $# -gt 1 ] &&{ echo "the args is error";exit;}
[ $# == 0 ] && read -s -p "please input script name: " name || name="$1"
echo "#!/bin/bash
# filename "$name"
# author:danran
# time isdate +%F
" >"$name"
chmod +x "$name"
vim "$name"
4键耕、編寫腳本,統(tǒng)計/etc柑营、/usr屈雄、/var目錄中有多少個一級子目錄和文件
#!/bin/bash
# danran
# time is Mon Jun 5 13:09:12 CST 2017
line1=ls $1 | wc -l
line2=ls $2 | wc -l
line3=ls $3 | wc -l
let sum=$line1+$line2+$line3
echo $sum
七、條件測試
判斷某需求是否滿足官套,需要由測試機制來完成棚亩;
Nnote:專用的測試表達式需要由測試命令輔助完成測試過程;
測試命令:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
Note:EXPRESSION前后必須有空白字符
bash的測試類型:
數(shù)值測試
-gt:大于
-ge:大于等于
-eq:等于
-ne:不等于
-lt:小于
-le:小于等于
字符串測試
==/=:等于
>:大于
<:小于
!=:不等于
~=:左側(cè)字符是否能被右側(cè)的PATTERN所匹配
Note:一般用于[[ ]]中
-z “STRING” 測試字符串是否為空虏杰,空為真,不空為假
-n “STRING” 測試字符串是否不空勒虾,不空為真纺阔,空為假
eg [ -z "$name" ]
[[ $name ~= ^a ]] 匹配$name是否a開頭
Note:用于字符串比較時的用到的操作數(shù)都應(yīng)使用引號
文件測試
存在性測試:
-a:FILE 同-e
-e:FILE:文件存在性測試,存在為真
存在性及類別測試:
-b FILE:是否存在且為塊設(shè)備文件
-c FILE:是否存在且為字符設(shè)備文件
-d FILE:是否存在且為目錄文件
-f FILE:是否存在且為普通文件
-S FILE:存在且為套接字文件
-L FILE 或 -h FILE:存在且為鏈接文件
-p FILE:是否存在且為命名管道文件
文件權(quán)限測試:(當(dāng)前用戶)
-r:文件是否存在且可讀
-w:文件是否存在且可寫
-x:文件是否存在且可執(zhí)行
文件特殊權(quán)限測試:
-g FILE:文件存在且擁有g(shù)uid權(quán)限修然,suid對腳本無效笛钝,腳本不是二進制文件
-u FILE:文件存在且擁有suid權(quán)限
-k FILE:是否存在且擁有sticky權(quán)限
文件大小測試:
-s FILE:文件是否存在且非空
文件打開性測試:
-t fd:fd表示文件描述符是否已經(jīng)打開且與某終端相關(guān)
-N FILE:文件自從上一次打開讀取之后是否被修改過
-O FILE:當(dāng)前有效用戶是否為文件屬主
-G FILE:當(dāng)前有效用戶是否為文件屬組
雙目測試:
FILE1 -ef FILE2:FILE1與FILE2是否指向同一個設(shè)備上的相同inode质况,即硬鏈接
FILE1 -nt FILE2:FILE1 是否新于FILE2
FILE1 -ot FILE2:FILE1 是否舊于FILE2
組合條件測試:
邏輯運算:
第一種方式:
COMMAND1 && COMMAND2 短路與
COMMAND1 || COMMAND2 短路或
! COMMAND 非
第二種方式:
[ EXPRESSION1 -a EXPRESSION2 ] 與
[ EXPRESSION1 -o EXPRESSION2 ] 或
!EXPRESSION 非
必須使用測試命令進行
[ -f /bin/cat -a -x /bin/cat ] && echo "true"
[ ! -r /app/a -a ! -w /app/a ] && echo true <==> [ ! \( -r /app/a -o -w /app/a \) ] && echo "true"
練習(xí):
1玻靡、編寫腳本/root/bin/excute.sh结榄,判斷參數(shù)文件是否為sh后綴的普通文件,如果是囤捻,添加所有人可執(zhí)行權(quán)限否則提示用戶非腳本文件
#!/bin/bash
[ $# == 0 ] && read -p "please input fimename" name || name=$1
[ -f $name ] && [[ "$name" =~ .sh$ ]] && chmod a+x $name || echo "$name not scripts file"
2臼朗、編寫腳本/bin/per.sh,判斷當(dāng)前用戶對指定的參數(shù)文件,是否不可讀并且不可寫
#!/bin/bash
[ ! -r $1 -a ! -w $1 ] && echo "$1 file not read and not write"
3蝎土、編寫腳本/root/bin/checkdisk.sh视哑,檢查磁盤分區(qū)空間和inode使用率,如果超過80%誊涯,就發(fā)廣播警告空間將滿
#!/bin/bash
inode=df -i | grep "^/dev/sd*" | tr -s ' ' '%'| cut -d'%' -f5| sort -r | head -n 1
disk=df | grep "^/dev/sd*" | tr -s ' ' '%'| cut -d'%' -f5| sort -r | head -n 1
[ $inode -gt 80 ] && echo "danran"
[ $disk -gt 80 ] && echo "dan"
八挡毅、bash自定義退出狀態(tài)碼
exit [n]:自定義退出狀態(tài)碼為n
Note:腳本中一旦遇到exit命令,腳本會立即終止暴构,終止退出狀態(tài)取決于exit命令后面的數(shù)字n跪呈。
Note:如果未給腳本指定退出狀態(tài)碼,整個腳本的退出狀態(tài)碼取決于腳本中執(zhí)行最后一條命令的狀態(tài)碼取逾。
練習(xí):編寫腳本/root/bin/argsnum.sh耗绿,接受一個文件路徑作為參數(shù);
如果參數(shù)個數(shù)小于1菌赖,則提示用戶“至少應(yīng)該給一個參數(shù)”缭乘,并立即退出;
如果參數(shù)個數(shù)不小于1琉用,則顯示第一個參數(shù)所指向的文件中的空白行數(shù)
#!/bin/bash
[ $# -lt 1 ] && (echo "please input a arge" && exit ) || echo "grep "^$" $1 | wc -l
"