1 Linux操作系統Shell
1.1 Shell腳本
當命令不在命令行中執行,而是從一個文件中執行時,該文件就稱為 Shell 腳本。
注意:
Shell腳本通常以.sh作為后綴名,但不是必須的。
Shell 腳本是以行為單位的,在執行腳本的時候會分解成一行一行依次執行。
Shell腳本是純文本文件
, Shell 是一種功能強大的解釋型編程語言
1.2 Shell腳本成分
1.2.1 Shell變量
定義變量時,變量名不加美元符號($)
變量名和等號之間不能有空格,這和其它編程語言不一樣,同時,變量名的命名須遵循的規則:
<1> 首個字符必須為字母(a-z,A-Z)
<2>中間不能有空格,可以使用下划線(_)
<3>不能使用標點符號
<4>不能使用bash里面的關鍵字(例如:cp)
1.2.2 輸入輸出
1、輸入
變量賦值
例如:name=1
從標准輸入讀取
read
例如:echo –e “what’s your name: \c”
read name
echo “my name is $name”
2、輸出
echo(常用)
1.2.3 Read
read:接收標准輸入(鍵盤)的輸入
例如:
#!/bin/bash //把下面的命令交給/bin下的bash執行 #The use of the read method //注釋read的用法 echo -n "Enter your name:" //-n :不換行顯示 read name //從鍵盤輸入 echo "hello $name,welcome to my family" //顯示信息
以上命令可以用-p進行濃縮(簡寫)
read -p "Enter your name:" name // -p:顯示提示信息 ,read后的變量只有name echo "hello $name,welcome to my family"
1.2.4 通配符
通配符是系統level的,通配符多用在文件名上,比如查找find,ls,cp,等等
在日常的 Linux 使用中,有很多時候可能需要一次對多個文件系統對象執行單一操作(比如 rm)。在這些情況下,在命令行中輸入許多文件通常讓人感到厭煩:
$ rm file1 file2 file3 file4 file5 file6 file7 file8
為了解決這個問題,可以利用 linux 內置的通配符支持。這種支持也叫做“globbing”(由於歷史原因),允許通過使用通配符模式一次指定多個文件。Bash 和其它 Linux 命令將通過在磁盤上查找並找到任何與之匹配的文件來解釋這種模式。因此,如果在當前工作目錄中,有從 file1 到 file8 的文件,那么可以輸入下面的命令來刪除這些文件:
$ rm file[1-8]
或者,如果只想要刪除文件名以 file 開頭的所有文件,可以輸入:
$ rm file*
或者,如果想要列出 /etc 中以 g 開頭的所有文件系統對象,可以輸入:
$ ls -d /etc/g*
現在,如果指定了沒有任何文件系統對象與之匹配的模式,會怎么樣呢?在下面的示例中,我們試圖列出 /usr/bin 中以 asdf 開頭並且以 jkl 結尾的所有文件:
$ ls -d /usr/bin/asdf*jkl
這里是對所發生情況的說明。通常,當我們指定一種模式時,該模式與底層系統上的一個或多個文件匹配,bash 以空格隔開的所有匹配對象的列表來替換該模式。但是,當模式不能找到匹配對象時,bash 將不理會參數、通配符等等,保留原樣。因此,當“ls”不能找到文件 /usr/bin/asdf*jkl 時,它會報錯。此處的有效的規則是:glob 模式只在與文件系統中的對象匹配時才可以進行擴展。
通配符語法:*
* 將與零個或多個字符匹配。這就是說“什么都可以”。例子:
* /etc/g* 與 /etc 中以 g 開頭的所有文件匹配。
* /tmp/my*1 與 /tmp 中以 my 開頭,並且以 1 結尾的所有文件匹配。
通配符語法:?
? 與任何單個字符匹配。例子:
* myfile? 與文件名為 myfile 后跟單個字符的任何文件匹配。
* /tmp/notes?txt 將與 /tmp/notes.txt 和 /tmp/notes_txt 都匹配,如果它們存在。
通配符語法:[]
該通配符與 ? 相似,但允許指定得更確切。要使用該通配符,把您想要匹配的所有字符放在 [] 內。結果的表達式將與 [] 中任一字符相匹配。您也可以用 - 來指定范圍,甚至還可以組合范圍。例子:
* myfile[12] 將與 myfile1 和 myfile2 匹配。只要當前目錄中至少有一個這樣的文件存在,該通配符就可以進行擴展。
* [Cc]hange[Ll]og 將與 Changelog、ChangeLog、changeLog 以及 changelog 匹配。您可以看到,與大寫形式的變形匹配時,使用括弧通配符很有用。
* ls /etc/[0-9]* 將列出 /etc 中以數字開頭的所有文件。
* ls /tmp/[A-Za-z]* 將列出 /tmp 中以大寫字母或小寫字母開頭的所有文件。
通配符語法:[!]
除了不與括弧中的任何字符匹配外,[!] 構造與 [] 構造類似,只要不是列在 [! 和 ] 之間的字符,它將與任何字符匹配。例子:
* rm myfile[!9] 將刪除除 myfile9 之外的名為 myfile 加一個字符的所有文件。
1.3 Shell腳本編碼規范
1、以#!開頭:通知系統用哪種解釋器執行腳本
#!/bin/bash(常用)
#!/bin/ksh
注:ksh在unix上使用較多;bash在linux上使用較多
2、注釋
以#開頭的行就是注釋,會被注釋器忽略。
1.4 Shell腳本的建立與執行
1、Shell腳本的建立
使用文本編輯器編輯腳本文件
vi test.sh
為腳本文件添加可執行權限
chmod +x test.sh
2、Shell腳本的執行
在子shell中執行
bash test.sh
sh test.sh
例如:
注:PATH 環境變量的默認值不包含當前目錄,若腳本文件在當前目錄,應使用 ./script-file(./代表當前目錄)
例如:./ test.sh
1.5 Shell腳本調試
1、sh –x 腳本名
該選項可以使用戶跟蹤腳本的執行,此時 shell 對腳本中每條命令的處理過程為:先執行替換,然后顯示,再執行它。
shell 顯示腳本中的行時,會在行首添加一個加號 “ + ”
2、sh –v 腳本名
在執行腳本之前,按輸入的原樣打印腳本中的各行
3、sh –n 腳本名
對腳本進行語法檢查,但不執行腳本。如果存在語法錯誤,shell 會報錯,如果沒有錯誤,則不顯示任何內容。
1.6 Shell腳本類型
1、交互式腳本
腳本可以讀取用戶的輸入, 實時向用戶反饋信息(輸出某些信息)
這樣的腳本更靈活, 每次執行時的參數可由用戶動態設定
用戶界面更友好,但不適用於自動化任務(如cron任務)
簡單的來說就是:交互式模式就是shell等待你的輸入,並且立即執行你提交的命令
2、非交互式腳本
不需要讀取用戶的輸入, 也不用向用戶反饋某些信息
每次執行都是可預見的, 因為它不讀取用戶輸入, 參數是固定的
可以在后台執行
簡單來說:shell不與你進行交互,而是讀取存放在文件中的命令,並且執行它們。當它讀到文件的結尾,shell也就終止了。
1.7 流程控制語句
1.7.1 IF
if 語句通過關系運算符判斷表達式的真假來決定執行哪個分支。Shell 有三種語句:
if …fi語句
if ... else ... fi 語句;
if ... elif ... else ... fi 語句。
1、 if … fi語句
格式:
if 【條件表達式】
then
語句塊
fi
如果條件表達式返回true,那么then后的語句塊將被執行,如果返回false,不會執行任何語句
2、if ... else ... fi 語句
格式:【條件表達式】
then
語句塊1
else
語句塊2
fi
3、if ... elif ... fi 語句
1.7.2 While
while expr //執行expr
do //若expr的退出狀態為0,進入循環,否則退出while
commands //循環體
done //循環結束標志,返回循環頂部
1.7.3 FOR
for 變量 in 值1 值2...
do
代碼
Done
1.8 作業
- 監控內存,超過20%后,報警且保存到mem.log文件
#!/bin/bash #This is monitor the usage of mem #And if the usage rate exceeds 20%,please check it #Get the Total and used Total=`free -m | sed -n '2p' | awk '{ print $2 }'` Used=`free -m | sed -n '2p' | awk '{ print $3 }'` #Get the usage usage=`echo "$Used * 100 /$Total" | bc` #whether rate is exceeds than 20% if [ $usage -ge 20 ] then echo -n `date "+20%y-%m-%d %H:%M:%S"` >> /home/wuzhenru/mem.log echo -e "\tWaring: The usage of MEM is $usage%, please check it." >> /home/wuzhenru/mem.log else echo -n `date "+20%y-%m-%d %H:%M:%S"` >> /home/wuzhenru/mem.log echo -e "\tThe usage of MEM is OK !" >> /home/wuzhenru/mem.log fi
懸鏡占用內存總和統計,且當總和大於2%時,將對應的時間及內存量寫在日志中。
執行結果:
Jll.log