初識Shell——bashmysql
Linux中的shell有點相似Windows下的cmd.exe或者.bat。管理整個計算機硬件的實際上是操做系統的內核(Kernel),用戶沒法與內核直接交互,因此經過shell來跟內核通訊。即shell介於操做系統(Kernel)和用戶之間,它是用戶與內核的翻譯官,是一個命令解釋器。linux
常見的shell種類有:Bsh、Csh、Ksh、Bash、Zshgit
Bsh和Csh出現的較早,Ksh繼承了它兩的功能,Bash繼承了Bsh和Ksh的升級版,並且是Linux系統中默認的shell,Zsh則兼具了各類shell的程序有點,交互式操做效率更高,但仍不及bash應用普遍。sql
Shell環境的切換:shell
登陸Shell:指用戶每次登陸系統後自動加載的Shell程序,大多數Linux系統採用 /bin/bash 做爲默認登陸Shell;/etc/shells 文件記錄了系統支持的有效登陸Shell編程
[root@localhost ~]# cat /etc/shells ==>使用chsh -l命令也可查看 /bin/sh /bin/bash /sbin/nologin /bin/tcsh /bin/csh /bin/ksh [root@localhost ~]#
默認的shell是bash,那麼如何切換shell環境呢?分爲兩種,一種是臨時切換,即當此終端關閉時,下次啓動仍然是bash,方法很簡單,直接在終端輸入shell名稱;第二種則是更改用戶登陸Shell,須要修改/etc/passwd文件中用戶記錄的最後一個字段,或者像前面講到的使用修改用戶的命令:usermod -s shell程序路徑 用戶名,也可使用chsh命令,下次登陸有效。安全
查看當前shell能夠經過/etc/passwd來查看,要查看系統默認使用的shell,可使用echo $SHELL。bash
bash的經常使用功能:函數
類型學習 |
設備文件 |
文件描述編號 |
默認設備 |
標準輸入 |
/dev/stdin |
0 |
鍵盤 |
標準輸出 |
/dev/stdout |
1 |
顯示器 |
標準錯誤輸出 |
/dev/stderr |
2 |
顯示器 |
(備註:/dev/stdin、/dev/stdout、/dev/stderr這三個文件是一個符號連接,輸入輸出與重定向關係緊密)
類型 |
操做符 |
用途 |
重定向標準輸入 |
< |
將命令中接收輸入的途徑由默認的鍵盤更改成指定的文件 |
重定向標準輸出 |
> |
將命令的執行結果輸出到指定的文件中,而不是直接顯示在屏幕上 |
>> |
將命令執行的結果追加輸出到指定文件 |
|
重定向標準錯誤 |
2> |
清空指定文件的內容,並將標準錯誤信息保存到該文件中 |
2>> |
將標準錯誤信息追加輸出到指定的文件中 |
|
重定向標準輸出和 標準錯誤 |
&> |
將標準輸出、標準錯誤的內容所有保存到指定的文件中,而不是直接顯示在屏幕上 |
管道操做符號是「|」,鏈接左右兩個命令,將左側的命令輸出的結果,做爲右側命令的輸入(處理對象)。管道是腳本語言的特點,它能夠講多個功能鏈接起來造成一個大的功能,這點與面向對象有很大的不一樣。
例如我如今要查看歷史記錄命令的第4行:則可先將前4條命令顯示出來,在顯示前4條命令的最後一條:history | head -4 | tail -1 這樣即取出了第四條命令。
Shell變量
Shell變量和其餘語言的變量含義大同小異,就是能夠存放不一樣的內容,它也爲靈活管理Linux系統提供特定參數。通常有兩層意思:變量名:使用固定的名稱,由系統預設或用戶定義;變量值:可以根據用戶設置、系統環境變化而變化。
Shell變量的種類:
變量的賦值與引用:
定義新的變量名要以英文字母或下劃線開頭,區分大小寫,格式爲:變量名=變量值
查看變量的值:echo $變量名
[root@localhost ~]# DAY=Sunday [root@localhost ~]# echo $DAY ==>經過$符號引用指定名稱的變量值 Sunday [root@localhost ~]#
(注意:在查看變量時,若是變量名容易和後邊的字符串連在一塊兒致使混淆,則應該使用大括號將變量名括起來,使用形式爲:${變量名} ,例如: 若已知變量Var的值爲Benet,則執行「echo $Var3.0」命令後將顯示結果「.0」而不是「Benet3.0」,由於在該命令中,會將「Var3」當成變量名(默認未定義此變量)。若但願正確顯示「Benet3.0」的輸出結果,則須要執行「echo ${Var}3.0」)
[root@localhost ~]# Var =Benet [root@localhost ~]# echo $Var Benet [root@localhost ~]# echo $Var3.0 .0 [root@localhost ~]# echo ${Var}3.0 Benet3.0 [root@localhost ~]#
從鍵盤輸入內容爲變量賦值,格式爲:read [-p "輸入信息"] 變量名
[root@localhost ~]#read var haha ==>這裏等待輸入 [root@localhost ~]#echo $var haha [root@localhost ~]#
在給變量賦值時,使用不一樣的引號操做的區別:
[root@localhost ~]#name=linuxidc [root@localhost ~]#echo $name linuxidc [root@localhost ~]#myname="$name is me" ==>這裏使用的是雙引號 [root@localhost ~]#echo $myname linuxidc is me ==>將$name這個變量執行出來了 [root@localhost ~]#myname='$name is me' ==>這裏使用的是單引號 [root@localhost ~]#echo $myname $name is me ==>原樣顯示出來了,$name沒有執行 [root@localhost ~]#
[linuxidc@localhost ~]$ locate crontab /etc/anacrontab /etc/crontab /usr/bin/crontab /usr/share/man/man1/crontab.1.gz ..... [linuxidc@localhost ~]$ ls -l `locate crontab` ==>先執行locate crontab,再執行ls -l -rw-r--r-- 1 root root 298 2006-12-18 /etc/anacrontab -rw-r--r-- 1 root root 255 2006-07-15 /etc/crontab -rwsr-sr-x 1 root root 315416 2008-07-15 /usr/bin/crontab -rw-r--r-- 1 root root 1846 2008-07-15 /usr/share/man/man1/crontab.1.gz ..... [linuxidc@localhost ~]$
設置變量的做用範圍,格式:export 變量名
通常狀況下,父進程的自定義變量是沒法在子進程中使用的,可是經過export將變量變成環境變量後,就可以在子進程下使用了。
[root@localhost ~]#name=linuxidc [root@localhost ~]#echo $name linuxidc [root@localhost ~]# export name ==>輸出爲全局變量 [root@localhost ~]# zsh [root@localhost]~# echo $name linuxidc [root@localhost]~# exit [root@localhost root]# unset name==>消除變量內容 [root@localhost root]# echo $name [root@localhost ~]#
變量還有一個好處,當您常常訪問一個目錄時,並且這個目錄比較長,能夠將它付給一個簡單的變量,這樣進入這個目錄時候只需cd 變量就好了。如work="~/temp/2013/test/",則進入這個目錄只需cd work。
數值變量的運算:
以前講到過可使用命令bc來打開一個計算器,其實Bash程序並不適合進行強大的數學運算,例如小數或指數運算的,通常只能進行簡單的整數運算,若不使用bc,則也可使用下列格式來進行簡單數值計算:
格式:expr 變量1 運算符 變量2 [..運算符 變量n...]
expr命令經常使用的運算符有:+、-、\*(注意要有\)、/、%
[linuxidc@localhost ~]$ expr 10 * 2 expr :語法錯誤 [linuxidc@localhost ~]$ expr 10 \* 2 20 [linuxidc@localhost ~]$expr 10 + 2 12 [linuxidc@localhost ~]$
環境變量
環境變量配置文件:全局配置文件:/etec/profile
用戶配置文件:~/.bash_profile
查看環境變量:env
set (set命令能夠查看全部的Shell變量,其中包括環境變量)
常見的環境變量:
位置變量:
表示爲$n,n爲1~9之間的數字,$n的做用就是爲腳本文件傳遞執行參數。
[linuxidc@localhost ~]ls -a -l -l ==>a就是第1個位置變量,依次類推,其實這個命令就是ls -al
預約義變量:
[root@localhost ~]# bash [root@localhost ~]# echo $0 $$ ==>查看當前所執行進程的名稱、PID號 -bash 32484 [root@localhost ~]# exxit ==>執行一條錯誤的命令 bash: exxit: command not found [root@localhost ~]# echo $? 127 ==>返回非0值,表示上一條命令異常 [root@localhost ~]# exit exit [root@localhost ~]# echo $? 0 ==>返回0,說明上一條命令正常
靈活使用這些變量,將大大加強Shell腳本程序的功能,$0做爲預約義變量,表示當前執行的程序名,須要與$1~$9的位置變量區分開。
引入shell腳本
shell腳本:
[root@localhost ~]# vi repboot.sh #!/bin/bash ==>聲明使用的shell環境,根據執行的方式不一樣可加可不加 # To show usage of /boot directory and mode of kernel file. echo "Useage of /boot: " du -sh /boot echo "The mode of kernel file:" ls -lh /boot/vmlinuz-* [root@localhost ~]# chmod a+x repboot.sh
編寫Shell腳本的簡單語法
提到編程,條件、分支、循環等語法確定少不了。shell腳本編程亦是如此,下面只是結合最近學習的一些簡單語法作的筆記,若有錯誤,歡迎指正。
if條件語句
條件測試操做
test命令:
用途:測試特定的表達式是否成立,當條件成立時,命令執行後的返回值爲0,不然爲其它值
格式:test 條件表達式 或者
[ 條件表達式 ](注意:方括號[]和條件表達式語句之間至少須要一個空格)
常見的測試類型:測試文件狀態;字符串比較;整數值比較;邏輯測試
測試文件狀態:[ 操做符 文件或目錄 ]
如何判斷當前所在的工做目錄是否爲 /usr/src? [ $PWD = 「/usr/src」 ] && echo 「YES」 || echo 「NO」
[root@localhost ~]# [ -d /etc/vsftpd ] [root@localhost ~]# echo $? 0 ==>返回值爲0,表示上一步測試的條件成立 [root@localhost ~]# [ -d /etc/hosts ] [root@localhost ~]# echo $? 1 [root@localhost ~]# [ -e /media/cdrom ] && echo "YES" ==>若是測試的條件成立則輸出「YES」 YES [root@localhost ~]# [ -e /media/cdrom/Server ] && echo "YES「 [root@localhost ~]#
上述&&是「與」的意思,「… && echo YES」表示若是沒有輸出,則表示前面執行的測試條件不成立或命令出錯。(備註:l測試文件是否可寫(-w)時,不要以root用戶(特權用戶)的身份執行測試,不然可能會沒法準確判斷)
整數值比較:[ 整數1 操做符 整數2 ]
[root@localhost ~]# who | wc -l 5 [root@localhost ~]# [ `who | wc -l` -le 10 ] && echo "YES" ==>若是登陸用戶數小於或等於10則輸出YES YES [root@localhost ~]# df -hT | grep "/boot" | awk '{print $6}' 12% [root@localhost ~]# BootUsage=`df -hT | grep "/boot" | awk '{print $6}' | cut -d "%" -f 1`
[root@localhost ~]# echo $BootUsage 12 [root@localhost ~]# [ $BootUsage -gt 95 ] && echo "YES" ==>若是/boot分區的磁盤使用率超過95%則輸出YES
條件測試操做:[ 字符串1 = 字符串2 ]
[root@localhost ~]# read -p "Location:" FilePath Location:/etc/inittab [root@localhost ~]# [ $FilePath = "/etc/inittab" ] && echo "YES" ==>若是鍵入路徑與指定的目錄一致則輸出YES YES [root@localhost ~]# [ $LANG != "en.US" ] && echo $LANG ==>若是當前的語言環境不是en_US,則輸出LANG變量的值 zh_CN.UTF-8
(字符串比較能夠用於檢查用戶輸入,例如在提供交互式操做時,判斷用戶輸入的選擇項是否與指定的變量內容相匹配)
邏輯測試:[ 表達式1 ] 操做符 [ 表達式2 ]
[root@localhost ~]# echo $USER root [root@localhost ~]# [ $USER != "teacher" ] && echo "Not teacher" ==>若是發現用戶不是teacher,則提示「Not teacher」 Not teacher [root@localhost ~]# [ $USER = "teacher" ] || echo "Not teacher" Not teacher
if語句結構——當「條件成立」時執行相應的操做
單分支:
if 條件測試命令
then 命令序列
fi
if語句簡單應用示例
#!/bin/bash temp=2 if [ $temp -eq 2 ] then echo 'temp is 2' fi
保存爲test文件,並將它設置爲可執行(+x)
[jzhou@localhost ~]# chmod 775 test
[jzhou@localhost ~]# bash test
temp is 2
(備註:lthen能夠寫到與if一行,但要用分號隔開,例如: if [ $RATE -gt 80 ] ; then)
單分支:
if 條件測試命令
then 命令序列1
else 命令序列2
fi
#!/bin/bash service mysqld status &> /dev/null if [ $? -eq 0 ] ==>判斷上句是否執行成功 then echo "mysqld service is running." else /etc/init.d/mysqld restart fi
提示用戶輸入一個整數,如何判斷該值是否小於100? read 「Input an integer:」 NUM ; if [ $NUM -lt 100 ] ; then echo 「小於100」 else echo 「大於或等於100」 fi
多分支:
if 條件測試命令1 ; then
命令序列1
elif 條件測試命令2 ; then
命令序列2
elif ...
else
命令序列n
fi
for循環語句——根據變量的不一樣取值,重複執行一組命令操做
for語句的結構
for 變量名 in 取值列表
do
命令序列
done
for語句簡單應用示例
依次輸出3條文字信息,包括一天中的「Morning」、「Noon」、「Evening」字串 [root@localhost ~]# vi showday.sh #!/bin/bash for TM in "Morning" "Noon" "Evening" do echo "The $TM of the day." done
[root@localhost ~]# sh showday.sh The Morning of the day. The Noon of the day. The Evening of the day
示例2:得到用戶的知足條件的文件數
#!/bin/bash DIR="/opt" LMT=100 ValidUsers=`grep "/bin/bash" /etc/passwd | cut -d ":" -f 1` ==>得到使用bash做爲登陸shell的用戶名列表 for UserName in $ValidUsers do Num=`find $DIR -user $UserName | wc -l` if [ $Num -gt $LMT ] ; then echo "$UserName have $Num files." fi done
[root@localhost ~]# sh chkfileown.sh root have 6737 files. teacher have 344 files.
while循環語句——重複測試指定的條件,只要條件成立則反覆執行對應的命令操做
while語句的結構
while 命令或表達式
do
命令列表
done
while語句簡單應用示例
批量添加20個系統用戶賬號, 用戶名依次爲「stu1」、「stu2」、……、「stu20」 #!/bin/bash i=1 while [ $i -le 20 ] do useradd stu$i echo "123456" | passwd --stdin stu$i &> /dev/null i=`expr $i + 1` done
批量刪除上述添加的20個系統用戶賬號 #!/bin/bash i=1 while [ $i -le 20 ] do userdel -r stu$i i=`expr $i + 1` done
分支控制語句
case語句——根據變量的不一樣取值,分別執行不一樣的命令操做
case 變量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
……
* )
默認執行的命令序列
esac
(當遇到雙分號「;;」後跳轉至esac表示結束分支。若是一直找不到相匹配的值,則執行最後一個模式「*)」後的默認命令序列,直到遇到esac後結束分支)
#!/bin/bash case $1 in start) echo "Start MySQL service." ;; stop) echo "Stop MySQL service." ;; *) echo "Usage:$0 start|stop" ;; esac
(/etc/init.d/ 目錄下的各種腳本中,大量使用了case分支語句結構)
#!/bin/bash read -p "Press some key, then press Return:「 KEY case "$KEY「 in [a-z]|[A-Z]) echo "It's a letter." ;; [0-9]) echo "It's a digit." ;; *) echo "It's function keys、Spacebar or other keys. " esac
(匹配模式中可使用方括號表示一個連續的範圍,例如「[0-9]」;使用豎槓符號「|」表示或,例如「A|B」(A或者B))
unitl語句——根據條件執行重複操做
until 條件測試命令
do
命令序列
done
(•until 循環的結構與while命令相似,「until經過檢測其後接命令的返回值「$?」來判斷是否退出循環
•until:直到」測試條件「成立時終止循環,而while是:當」測試條件「成立時進行循環
•即:until在測試條件爲假(非0)時執行循環,條件爲真時(0)退出循環,正好與while循環相反)
shift語句——用於遷移位置變量,將 $1~$9 依次向左傳遞(不經常使用)
經過命令行參數傳遞多個整數值,並計算總和 [root@localhost ~]# vi showday.sh #!/bin/bash Result=0 while [ $# -gt 0 ] ==> $# 爲預約義變量,表示位置參數的個數
do
Result=`expr $Result + $1` shift done echo "The sum is : $Result"
[root@localhost ~]# ./sumer.sh 12 34 56 The sum is : 102
循環控制語句
break:在for、while、until等循環語句和case中用於跳出當前的循環體,執行循環體後的語句;並不退出程序。執行break命令後將跳到done語句以後。
continue:在for、while、until等循環語句中,用於跳過循環體內餘下的語句,從新判斷條件以便執行下一次循環
shell函數應用
定義新的函數:
調用已定義的函數: 函數名
向函數內傳遞參數:函數名 參數1 參數2 ......
#!/bin/bash adder() { echo `expr $1 + $2` } adder 12 34 adder 56 789
[root@localhost ~]# sh adderfun.sh 46 845