20 shell腳本編程1
一、雜項知識整理
1、腳本文件格式:
#!/bin/bash
(注釋信息:)
#description:say hello
#vesion:1.4.
#author:Jerry
#date:20160718
(代碼注釋:)
(縮進 適度添加空白行)
shell腳本的用途有:
自動化常用命令
執行系統管理和故障排除
創建簡單的應用程序
處理文本或文件
2、運行腳本的兩種方式:
bash file.sh
chmod +x file.sh . file.sh
腳本調試:
bash -n 檢查腳本中的語法錯誤
bash -x 調試執行,顯示執行過程
3、變量:
變量:命令的內存空間
數據存儲方式:
字符:
數值:整型,浮點型
作用:
數據存儲格式
參與的運算
表示的數據范圍
類型:
字符型
數值型:整型,浮點型
命名法則:
不能使用程序中的保留字如if for等
只能使用數字、字母及下劃線,且不能以數字開頭
見名知義
統一命名規則:駝峰命名法
4、bash中的算數運算:help let
+ – * / %取余 **乘方
實現算術運算:let var=算術表達式
var=$[expr]
賦值公式中等號兩邊不能有空格,有空格的是比較運算。
var=$((expr))
var=$(expr arg1 arg2 arg3…)
declare -i var=數值
echo ‘算數表達式’ | bc
乘法符號有些場景中需要轉義,expr 3 \* 4,expr沒有乘方運算
使用expr的時候需要每個字符串都加空格,否則識別為一個字符串:expr 1 + 3
使用bc命令可以使用計算器,重定向給計算器也可以進行計算,bc計算器可以直接使用正常算法格式如23+25,2^4等。
其中乘方使用bc如上,使用其他方式的時候是**,如
[root@centos68 tmp]# let a=2**4 [root@centos68 tmp]# echo $a 16
bash有內建的隨機數生成器:$RANDOM(1-32767)
echo $[RANDOM%50] :0-49之間的隨機數
echo $[RANDOM%50+1]:取余之后的結果加1,表示1-50之間的隨機數。
5、增強型復制:
+= -= *= /= %= 自身進行運算之后再賦值給自己
自增自減:let var+=1
let var++
a++ 和 ++a是有區別的,運算順序不一樣
let var-=1
let var–
6、短路運算:
短路與:第一個為0,結果必定為0
第一個為1,第二個必須要參與運算
短路或:第一個為1,結果必定為1
第一個為0,第二個必須要參與運算
異或:^ 異或的兩個值,相同為假,不同為真
7、兩種聚集命令的方法:
復合式:date;who | wc -l 命令會一個接一個地運行
子shell:(date;who | wc -l) >>/tmp/trace 所有的輸出都被發送給單個stdout和stderr。
8、測試命令:
test EXPRESSION
格式相同,就是去掉了括號
[ EXPRESSION ]
[[ EXPRESSION ]] EXPRESSION前后必須有空白字符
如test a = b [ a = b ] [[ a = b ]]
數值測試:
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于
-eq 是否等于
-ne 是否不等于
字符串測試:
== 是否等于
> 是否大于 acsii碼
< 是否小于
!= 是否不等于
=~ 左側字符串是否能夠被右側的PATTERN所匹配。注意,此表達式一般用于[[]]中
-z “string” 字符串是否為空,空為真,不空為假
-n “string” 字符串是否為不空,不空為真,空為假
注意:用于字符串比較時的用到的操作數都應該使用引號。
文件測試:
-a FILE 文件存在性測試,存在為假,否則為真
-e FILE 文件存在性測試,存在為真,否則為假
-b FILE 是否存在且為塊設備文件
-c FILE 是否存在且為字符設備文件
-d FILE 是否存在且為目錄文件
-f FILE 是否存在且為普通文件
-h FILE 或-L FILE 存在且為符號鏈接文件
-p FILE 是否存在且為管道文件
-S(大寫) FILE 是否存在且為套接字文件
-r FILE 是否存在且可讀
-w FILE 是否存在且可寫
-x FILE 是否存在且可執行
檢測的是實際權限,與顯示的權限位不一定相同,例如root
-g FILE 是否存在且擁有sgid權限
-u FILE 是否存在且擁有suid權限
-k FILE 是否存在且擁有sticky權限
-s(小寫) 是否有內容,有內容為真
-t fd:fd表示文件描述符是否已經打開且與某終端相關
-N FILE 文件自上一次被讀取之后是否被修改過
-O FILE 當前有效用戶是否為文件屬主
-G FILE 當前有效用戶是否為文件屬組
雙目測試:FILE1 -ef FILE2:兩個文件是否指向同一個設備上的相同inode
FILE1 -nt FILE2 :FILE1是否新與FILE2
FILE1 -ot FILE2 : FILE1是否舊于FILE2
8、組合測試條件:
第一種方式:
COMMAND1 && COMMADN2 并且
COMMAND1 || COMMAND2 或者
!COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
第二種方式:
EXPR1 -a EXPR2 并且
EXPR1 -o EXPR2 或者
!EXPR 非
必須使用測試命令進行
9、查看所有內部命令:man bash 或 enable
同名文件用mv和cp兩個命令覆蓋的區別:mv是改變了其索引,inode號沒有變,也就是指元數據沒變化。cp覆蓋是新建了文件,數據也重新遷移,inode號也就改變了。
10、Linux中運行命令或者腳本,按照PATH變量給定的路徑。windows先搜索當前目錄再按照path變量尋找。
11、netstat -nt 查看活動網絡連接;touch /etc/nologin,可以禁止普通用戶登錄!另外可以usermod -L和-U 以及passwd -l和-u進行禁止。
12、
二、練習及課后作業
1、變量類型及區別:
本地變量:生效范圍是當前shell進程;對低昂前shell之外的其他shell進程,包括當前shell的子shell進程均無效。
賦值name=‘value’ 可以使用引用value,可以是直接字串name=“root”;變量引用:name=“$USER”;命令引用:name=`command` name=$(command)
變量引用:${name} $name
"" 弱引用,其中的變量引用會被替換為變量值
‘’強引用,其中的變量引用不會被替換為變量值
顯示已定義的所有變量:set
刪除變量:unset name(在腳本執行結束后一定要刪除使用的變量以清空內存空間)
環境變量:生效范圍為當前shell進程及子進程
環境變量:變量聲明、賦值:export name=VALUE
declare -x name=VALUE
變量引用:$name $(name)
顯示所有環境變量:export env printenv
刪除:unset name
局部變量:生效范圍為當前shell進程中某代碼片段(通常指函數)
位置變量:$1,$2…來表示,用于讓腳本代碼中調用通過命令行傳遞給它的參數
只讀變量:readonly name
declare -r name
也可以同時設置為環境變量
在腳本代碼中調用通過命令行傳遞給腳本的參數
$1 $2…${10}…對應第1 第2…第10個參數,shift [n] 換位置
特殊變量:$?上一條命令的執行返回值,錯誤為0,正確為1-254
$0 腳本文件路徑本身
$@ 傳遞給腳本的所有參數,每個參數為獨立字符串
$# 顯示使用了哪幾個參數
$* 傳遞給腳本的所有參數,全部參數合為一個字符串
$@和$*只在被雙引號包起來時候才會有差異
2、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。
1 #!/bin/bash 2 #test 1 3 #info 4 5 echo "The hostname is : $(hostname)" 6 echo "The IP is: $(ifconfig | head -2 | tail -1 | tr -s " "| cut -d" " -f3)" 7 echo "The OS mode: $(cat /etc/system-release)" 8 echo "The kernel mode: $(uname -r)" 9 echo "The memory infomation: $(top | head -4 | tail -1 | cut -d: -f2)" 10 echo "The disk infomation : $(fdisk -l | grep "Disk /dev/sda:*" | cut -d, -f1 | cut -d: -f2)"
3、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中
1 #!/bin/bash 2 #test2 3 #bak 4 5 cp -rf /etc /root/etc$(date +%F) 6 #
4、編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值
#!/bin/bash echo "The max using rate is:`df |grep "/dev/sd"| cut -c 44-46 | sort -nr | head -1`%" [root@centos68 shelltest]# bash disk.sh The max using rate is: 41%
5、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序。
#!/bin/bash #test 4 #Des echo "the links number is:" netstat -nt |tr -s ' ' |cut -d ' ' -f5 |cut -d: -f1 |grep [0-9]|sort |uniq -c|sort -nr
6、寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID和
#!/bin/bash #test 5 NUM1=`cat /etc/passwd | head -10 | tail -1 | cut -d: -f3` NUM2=`cat /etc/passwd | head -20 | tail -1 | cut -d: -f3` SUM=$[$NUM1+$NUM2] echo "The id sum is: $SUM" [root@centos68 shelltest]# bash -x sumid.sh ++ tail -1 ++ cut -d: -f3 ++ cat /etc/passwd ++ head -10 + NUM1=10 ++ cut -d: -f3 ++ tail -1 ++ cat /etc/passwd ++ head -20 + NUM2=499 + SUM=509 + echo 'The id sum is: 509' The id sum is: 509
7、寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和
#!/bin/bash #version #Des #test 2 NUM1=`cat $1 | grep "^$" | wc -l` NUM2=`cat $2 | grep "^$" | wc -l` SUM=$[$NUM1+$NUM2] echo "space lines: $SUM" unset NUM1 NUM2 SUM
8、寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件
#!/bin/bash #test8 #Des:acount NUM1=`ls -a /etc/ | wc -l` NUM2=`ls -a /var/ | wc -l` NUM3=`ls -a /usr/ | wc -l` SUM=$[$NUM1+$NUM2+$NUM3] echo "The acount of all files :$SUM
原創文章,作者:SilencePavilion,如若轉載,請注明出處:http://www.www58058.com/31941
文章整體結構清晰,層次分明,通過練習對shelll腳本基礎有了深刻的認識,希望能保持下去。