一、shell 簡介
shell
安裝必定邏輯關係記錄命令的文件,在此文件有執行權限的狀況下能夠用文件名稱發起腳本的指向,shell是一種解釋性語言,文件內記錄的動做須要解釋器shell。
vim
二、腳本的創建bash
2.1 vim test.shapp
通常狀況下腳本的結尾爲".sh"這不是系統規定的,可是是業界的一種規範ide
2.2 #!/bin/bash函數
腳本開頭的寫法,這是腳本的使用的解釋器,也就是腳本運行時的子shell字體
2.3 腳本的內容spa
腳本的內容是用命令和命令執行的邏輯關係組成
對象
2.4 腳本的執行方式ip
方法一 :sh + 腳本的名稱
方法二 :chmod +x 腳本
腳本名稱的調用
三、 腳本的編寫規範
1》開頭應該添加腳本的說明信息
[root@westosmaim ~]# vim /etc/vimrc map <F6> ms:callAddTile()<cr>'s function AddTile() call append(0,"#!/bin/bash") call append(1,"############") call append(2,"#Auther :feitian") call append(3,"#Email :feitian@westos.com") call append(4,"#Version :") call append(5,"#Description :test scripts") call append(6,"#Create_Date :".strftime("%Y-%m-%D")) call append(7,"#############") Endfunction
2》腳本中儘可能不要使用中文,哪怕用拼音代替
3》腳本中出現的()|[]|{}|<>等等成對出現的要一次打出,而且內容中的字符與這些符號之間要有空格
4》腳本中的語句要一次寫完在豐富內容
5》語句中使用的動做要縮進寫入,使腳本易讀
4. 在書寫腳本過程當中咱們用到的命令
4.1 diff命令
diff命令是用來比較兩個文件的不一樣,通常咱們比較文件的內容是都是使用vimdiif,覺得他看起來更清楚,高亮顯示不一樣的行。可是diff能夠用來打補丁
[num1,num2][a|c|d][num3,num4] #a是添加的意思 #c是改變的意思 #d刪除的意思 #num1,num2是第一個文件的內容 #num3,num4是第二個文件的內容
使用diff命令打補丁
diff -u file1 file2 >file.path #生成補丁文件 patch file1 file.patch #給file1打補丁,打完補丁以後,他就和file2相同 patch -b file1 file.patch #備份原文件爲file.orgi
4.2 grep命令
-n |
只顯示過濾出來的那一行 |
-E |
多層過濾 |
-n3 |
顯示過濾出來的上下3行(共7行) |
^test |
以test開頭的內容 |
-A3 |
顯示過濾出來的前邊4行(共4行) |
test$ |
以test結尾的內容 |
-B3 |
顯示過濾出來的後邊4行(共4行) |
"\<test" |
以test開頭的內容 |
-i |
對原文件就行修改 |
"test\>" |
以test結尾的內容 |
-v |
除了包含過濾字符的內容 |
^$ |
空行 |
4.3 cut命令
cut -c 1-4|1,4 #打印文件2每行的前4個字符 cut -d 分隔符 -f 要打印的域 file
一個關於cut和grep的簡單腳本 :打印出系統eth0的ip,如過由兩塊網卡,則下面會介紹方法。
[root@client scripts]# vim ip_print.sh #!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/22/17 ############# IP=`ifconfig | grep "inet\>" |grep -v 127.0.0.1|cut -d " " -f 10` NAME=`ifconfig |grep mtu |grep -v lo | cut -d ' ' -f 1` echo "$NAME$IP" [root@client scripts]# sh ip_print.sh eth0:192.168.0.100
4.4 awk 命令
TEST=`############################` awk -F 分隔符 -v TEST=$TEST 'BEGIN {print TEST} {print $2} END {print TEST} /etc/passwd #可使用特殊
一個簡單的有關awk的腳本,仍是剛纔的問題,打印系統的網卡,此次就是多塊網卡。
[root@client scripts]# vim ip_print.sh #!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/22/17 ############# NAME=`cat /proc/net/dev |egrep "Inter|face|lo" -v|awk -F : '{print $1}'` for Device_Name in $NAME do ifconfig $Device_Name | grep "inet\>" |awk -F " " -v INTERFACE=$Device_Name 'BEGIN {print INTERFACE} { print $2}' done [root@client scripts]# sh ip_print.sh eth0 192.168.0.100 eth1 192.168.1.100
4.5 使用不一樣底色和不一樣顏色的字體
有關字體的顏色編號:
字體背景顏色 |
所對應的編號 | 字體顏色 |
所對應的編號 |
40 | 黑色 |
30 | 黑色 |
41 |
深紅色 |
31 | 紅色 |
42 |
綠色 |
32 | 綠色 |
43 |
××× |
33 | ××× |
44 | 藍色 |
34 |
藍色 |
45 |
紫色 |
35 |
紫色 |
46 |
深綠色 |
36 |
深綠色 |
47 |
白色 |
37 |
白色 |
圖
一個簡單10秒倒計時輸出結果的字體爲紅色
#!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/22/17 ############# for i in {10..1} do echo -ne "\033[31m$i \033[0m " echo -ne "\r \r" sleep 1 done
5. 腳本中的變量
5.1 變量的命名規則
變量中只能包含字母,數字和下滑線,他的寫法通常爲這3種 :TEST_REDAHAT,Test_Read和testReadhat.
關於變量的一個簡單腳本,其實在前邊咱們已經用到變量,其實就是參數傳遞的做用。這裏咱們寫一個創建用戶的腳本,給定一個文件,讓你把這個文件中的用戶創建出來
[root@client scripts]# vim useradd.sh #!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/22/17 ############# Max_Line=`wc -l /scripts/username|cut -c 1` for Line_Number in `seq 1 $Max_Line` do Username=`sed -n ${Line_Number}p /scripts/username` useradd $Username done [root@client scripts]# sh useradd.sh [root@client scripts]# sh useradd.sh useradd: user 'username1' already exists useradd: user 'username2' already exists useradd: user 'usernaem3' already exists
5.2變量的設定方式
環境級變量:在當前環境生效,當前環境關閉,變量失效
[root@client scripts]# export A=1 [root@client scripts]# echo $A 1
用戶級變量:只針對設置過的用戶生效,其餘用戶沒法使用
在用戶的家目錄中修改,也就是文件/root/.bash_profile或者/student/.bash_profile
系統別名的設定也分爲2個級別,他和系統變量的級別差很少,只是少一個環境級,他有用戶級和系統級別名
用戶級:在文件也是在用戶的家目錄下的.bashrc
[root@westosmaim~]# vim /root/.bashrc alias day='date' [root@westosmaim~]# source /root/.bashrc [root@westosmaim~]# day Tue Aug 2221:29:40 EDT 2017
系統級別名:系統級別名在/etc/bashrc,添加方式和系統級別名添加方式同樣。
$1 執行腳本時表明的第一串字符串
$2 同理,執行腳本中時表明的第二串字符串
$* 執行腳本時後面跟的全部字符串
$# 執行腳本時後面跟的字符串的個數
$? 執行腳本成功時返回0,執行腳本失敗時返回非零。
[root@westosmaim scripts]# vim test.sh #!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/22/17 ############# echo '$1 is '$1' ' echo '$1 is '$2' ' echo '$* is '$*' ' echo '$# is '$#' ' [root@westosmaim scripts]# sh test.sh lala hehe $1 is lala $1 is hehe $* is lala hehe $# is 2
注意:在重複兩個單引號時能夠抵消,好像是沒有同樣。
[root@westosmaim scripts]# echo $A 1 [root@westosmaim scripts]# echo '$A' $A [root@westosmaim scripts]# echo ''$A'' 1
這裏穿插二個簡單的腳本,第一個判斷一個網段的ip是否是通的
#!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/22/17 ############# echo "please input ip that netmask is (255.255.255.0) " echo "please input ip that as 172.25.254" for i in {1..254} do ping -w1 -c1 $1.$i &> /dev/null && echo"$1.$i is up" || echo "$1.$i is down" done
使用test 能夠用來做爲變量的比較,在下面的腳本中有使用到 "$WANT" = "C" 判斷WANT 的值等不等於C。
TEST() { echo test } #函數體 TEST #對函數的調用
這裏穿插一個簡單的腳本,就是判斷一個網段的IP是否是通的。
#!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/22/17 ############# ACTION() { read -p "please input a IP that it will be checked: " IP ping -w1 -c1 $IP &>/dev/null && echo "$IP is up" || echo "$IP is down" } CHECK() { read -p "what will you do? please inputQUIT(Q) or CHECK(C)" CHECK WANT=`echo $CHECK|tr a-z A-Z` test "$WANT" = "C" && ( ACTION CHECK) test "$WANT" == "Q" && exit 0 } MAIN
#這個也可使用case語句 #!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/22/17 ############# ACTION() { read -p "please input a IP that it will be checked: " IP ping -w1 -c1 $IP &>/dev/null && echo "$IP is up" || echo "$IP is down" } CHECK() { read -p "what will you do? please inputQUIT(Q) or CHECK(C)" CHECK WANT=`echo $CHECK|tr a-z A-Z` case $WANT in C) ACTION CHECK ;; Q) exit 0 ;; *) echo "please inputQ or C" ;; esac } CHECK
注意:這裏舉例均爲正確的
[root@westosmaim scripts]# echo $A 1 [root@westosmaim scripts]# [ "$A"= "1" ]&& echo yes || echo no yes [ 「1」 = 「1」 ] [ 「2」 > 「1」 ] [ 「1」 < 「2」 ] [ 「1」 != 「2」] #注意在「[」和「]」和你的比較對象之間必需要有空格 [ 「$A」 -eq 「1」 ] #1等於1 [ 「$A」 -ne 「2」 ] #1不等於二 [ 「2」 -gt 「$A」 ] #2大於1 [ 「1」 -ge 「$A」 ] #1大於等於1 [ 「$A」 -lt 「2」 ] #1小於2 [ 「$A」 -le 「1」 ] #1小於等於1 [ 「$A」 -eq 「1」 -a 「2」 lt 「3」 ] #1等於1而且2小於3 [ 「2」 -eq 「2」 -o 「1」 -gt 「2」 ] #2等於2或者1大於2,一個爲真則爲真。 [ -e /mnt/file ] #判斷/mnt/file是否是存在 [ -f /mnt/file ] #判斷/mnt/file是否是普通文件,若是不存在也是他也是返回非0 [ -x /mnt/file] #判斷/mnt/file是否是有執行權限,若是文件不存在也返回非0 [ -d /mnt/file] #判斷/mnt/file是否是一個目錄,若是不是也返回非0 [ -z 「helle」] #判斷是否爲空 #這裏有不少參數,好比-b -S -p等等,均可以判斷,讀者能夠本身理解,在前邊find命令時都有講過,這裏就不過多介紹了。
\ #轉義單個字符
‘’ #強引用
「」 #若引用,其轉義功能不能轉義「!」「$」 「\」 「`」
${A}1 #輸出爲11
[root@westosmaim scripts]# echo $A 1 [root@westosmaim scripts]# echo ${A}1 11 [root@westosmaim scripts]# echo $A1 #這裏輸出爲空,由於沒有A1這個變量
和c語言中的差很少,基本同樣。
++ i++ ==>i+1 #自加1
-- i-- ==>i-1 #自減1
+= i+=j ==>i=i+j
-= i-=j ==>i=i-j
+ #加
- #減
* #乘
/ #除
% #取餘
** #冪預算
[root@westosmaim scripts]# echo $[3+2] 5 [root@westosmaim scripts]# let A=3+2 [root@westosmaim scripts]# echo $A 5 [root@westosmaim scripts]# echo `expr 3"+" 2` 5
#注意在expr做運算的時候,在「+」旁邊必須有空格
這裏寫一個簡單的例子,寫一個簡單的for語句的倒計時
#!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/23/17 ############# TIME=10 for((TIME;TIME>0;TIME--)) do echo -n "After ${TIME}s is end" echo -ne "\r \r" sleep 1 done
當你輸入一個字符串,他會他會反着輸出
#!/bin/bash ############## #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/21/17 ############## read -p "please iput alpha: " ALPHA Max=`echo -n $ALPHA |wc -m` for ((Max;Max>0;Max--)) do LALA=`echo -ne $ALPHA|cut -c $Max` echo -n $LALA done
這裏使用while寫一個簡單的倒計時爲1分10s的倒計時腳本
#!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/23/17 ############# TIME=10 MIN=1 for((TIME;TIME>=0;TIME--)) do while [ "$TIME" -eq"0" -a "$MIN" -gt "0" ] do echo -n "After $MIN:${TIME} is end " echo -ne "\r \r" sleep 1 ((MIN--)) TIME=59 done while [ "$TIME" -eq"0" -a "$MIN" -eq "0" ] do echo -ne "\r \r" clear echo "Time Out!!" exit 0 done clear echo -n " After $MIN:${TIME} isend " echo -ne "\r \r" sleep 1 done
這裏也是用一個腳原本更好的體現
#!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/23/17 ############# if [ -z $* ] then echo "please giveme a filename" elif [ -f $* ] then echo "$* is acommon file" elif [ -L $*] then echo "$* is alink" else echo $* is not exist fi
#這裏就不在多寫了,就是變量的判斷和if語句的運用
[root@westosmaim scripts]# sh panduan.sh /mnt/file /mnt/file is a common file 這裏寫一個進一步的腳本,給定兩個文件,一個文件中是用戶的名字,另外一個文件是用戶的密碼,必須是一一對應。
#!/bin/bash ############ #Auther :feitian #Email :feitian@westos.com #Version : #Description :test scripts #Create_Date :2017-08-08/23/17 ############# CHECK() { if [ "$#" -ne"2" ] then echo "echo pleasegive me usernemfile and userpasswdfile" elif ["$#" -eq"2" ] then Max_Line1=`wc -l$1|awk -F " " '{print $1}'` Max_Line2=`wc -l$1|awk -F " " '{print $1}'` if ["$Max_Line" -ne "$Max_Line2" ] then echo "Thefile usernemfile don't muth userpasswdfile,please check it" else echo"lala" fi fi } CHECK