學習Shell腳本編程
導航
一. Shell入門概述
1.1 概述
- Linux最經典的就是Shell,它是操作系統的最外層,它可以合併編程語言以控制進程和文件,以及啓動和控制其他程序;
- shell通過提示您輸入,向操作系統解釋該輸入,然後處理來自操作系統的任何結果輸出來管理您與操作系統之間的交互。
- Shell是用戶與Linux操作系統之間溝通的橋樑。用戶可以輸入命令執行,又可以利用Shell腳本編程去運行。
簡單來說Shell就是一個用戶跟操作系統之間的一個命令解釋器;
1.2 Linux Shell的種類
- Linux Shell種類非常多,常見的有: Bourne Shell (/usr/bin/sh或/bin/sh)、Bourne Again Shell (/bin/bash) 、 C Shell(/usr/bin/csh)、K shell(/user/bin/ksh)、Shell for Root(/sbin/sh)等。不同的Shell語言的語法有所不同,所以不能交換使用。
1.3 創建我的第一個腳本 Hello,world
- 創建第一個腳本
vi first_shell.sh
- 對腳本編輯內容
#!/bin/bash
#Filename: first_shell.sh
#auto echo hello world!
#by authors zhang 2019
echo "Hello,world"
- 編輯完成後使用ESC退出插入模式,然後輸入 ** : + wq ** 退出;
- 給予執行權限:
chmod o+x first_shell.sh
- 運行:
./first_shell.sh
使用此命令後,就會出現輸出的Hello,world;同時我們也可以使用下方命令輸出內容:
/bin/bash first_shell.sh
腳本中,第一行的#!/bin/bash
內容是標註它是一個Shell腳本(固定格式),第二行表名名稱,第三行是描述,第四行是作者和寫腳本的日期,除了第一行是表明它是一個腳本外,其他行都是註釋的內容;
執行腳本和執行命令是沒有區別的,但是腳本里面可以包含很多條命令,而命令只能一次執行一次,效率較低;比如你同時要往十個服務器中部署一樣的東西,那麼腳本執行就可以省卻大量的時間;
二. 變量及LAMP導航菜單編寫
2.1 變量的詳解
- Shell編程語言是非類型的解釋型語言,不像C++/JAVA語言編程時需要事先聲明變量,SHELL給一個變量賦值,實際上就是定義了變量,在Linux支持的所有Shell中,都可以用賦值符號(=)爲變量賦值,實際上就是定義了變量,在Linux支持的所有Shell中,都可以用賦值符號(=)爲變量賦值。
- Shell變量可分爲兩類:局部變量和環境變量。局部變量只在創建它們的Shell腳本中使用。而環境變量則可以在創建它們的Shell及其派生出來的任意子進程中使用。有些變量時用戶創建的,其他的則是專用Shell變量;
- 例如在腳本里面定義A=123,定義這樣一個變量,前面是變量名,後面是變量的值。
- 引用變量可以使用$變量名;
2.2 變量實戰示例
- 創建var.sh並編輯
vi var.sh
- 輸入內容:
#!/bin/bash
#define path variables
#by authors anyu 2019
name=anyu
echo "My name is $name"
- 按ESC退出插入模式,再使用 WQ 進行保存退出;
- 運行:
sh var.sh
運行後顯示結果: My name is anyu
這裏的demo是一個局部變量
2.3 系統變量
- 系統變量: 它是系統已經爲我們定義好了的變量,我們可以不用定義,直接使用即可
$0 當前程序的名稱(當前腳本的名稱)
$n 當前程序的第n個參數,n=1,2,3...9
$* 當前程序的所有參數(不包括程序本身)
$# 當前程序的參數個數(不包括程序本身)
$? 命令或程序執行完後的狀態,一般返回0表示執行成功
$UID 當前用戶的ID (結果爲0的是Root用戶)
$PWD 當前所在的目錄
- $n代碼示例:
echo $1 $2
-執行命令:
sh var.sh param1 param2
- 顯示結果:
param1 param2
從此可以看出,這裏的n來進行表示;
在變量的定義中我們可以使用 $變量名 來轉義,這樣的話這個$就不代表引用變量了,下面代碼示例
- 示例$1,?,#的作用
echo "The \$1 is $1"
echo "The \$2 is $2"
echo "The \$? is $?"
echo "The \$* is $*"
echo "The \$# is $#"
- 執行命令:
sh var.sh abc edf
- 顯示結果:
The \$1 is abc
The \$2 is edf
The \$? is 0
The \$* is abc edf
The \$# is 2
$1爲輸入的第一個參數,?爲判斷上一條命令是否執行成功,若執行成功則返回0,$*表示所有參數 KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲統計參數個數 在編譯apach…?在判斷上一條命令是否執行成功
2.4 自定義菜單
- 創建並編輯:
vi var1.sh
- 編輯內容如下:
#!/bin/bash
#auto print variables
# by anyu 2019-07
echo -e "\033[32mPlease select Menu follow:\033[1m"
echo "1)安裝apache服務器."
echo "2)安裝Mysql服務器."
echo "3)安裝PHP服務器."
echo "4)安裝LAMP WEB架構"
echo "--------------------------------------------"
- 顯示結果如下:
三. Shell編程之If條件語句
3.1 if條件判斷語句
- 語句句式如下:
if (表達式)
語句1
else
語句2
fi
fi作爲if條件語句的結尾
3.2 測試數字大小的if條件判斷案例
- 創建並編輯
vi if.sh
- 內容如下:
#!/bin/bash
# auto if test
# by anyu 2019
NUM1=100
NUM2=200
if(($NUM1> $NUM2));then
echo "This $NUM1 greate $NUM2 !"
else
echo "This $Num1 little $num2 !"
fi
- ESC保存WQ退出,執行下面命令:
/bin/bash/ if.sh
兩個小括號在if語句中是用來判斷大小的;
- 結果如下:
This 100 little 200 !
3.3 邏輯運算符解析:
-f 判斷文件是否存在 例如: if[-f filename]
-d 判斷目錄是否存在 例如: if[-d dir]
-eq 等於 應用於:整型比較
-ne 不等於 應用於:整型比較
-lt 小於 應用於:整型比較
-gt 大於 應用於:整型比較
-le 小於或等於 應用於:整型比較
-ge 大於或等於 應用於:整型比較
-a 雙方都成立(and) 邏輯表達式 -a 邏輯表達式
-o 單方成立(or) 邏輯表達式 -o 邏輯表達式
-z 空字符串
3.4 判斷文件夾是否存在的腳本案例
- 創建並編輯
vi if2.sh
- 內容如下:
#auto test files
#by authors anyu 2019
FILES=/tmp/test.txt
if [ ! -f $FILES ];then
echo "OK" >> $FILES
else
echo -e "\033[32m---------------\033[1m"
cat $FILES
fi
這個是用來判斷文件夾test.txt是否存在,如果存在則打印OK,如果不存在則創建並瀏覽;
- 使用命令執行:
/bin/bash if2.sh
3.5 IF條件語句之得分案例
- 創建並編輯
vi scores.sh
- 編輯內容如下:
#!/bin/bash
#by anyu 2019
scores=$1
if [ -z $scores ]; then
echo "usage: {$0 60|80.}"
exit
if
if [[ $scores -gt 85 ]]; then
echo "very good!";
elif [[ $scores -gt 75 ]]; then
echo "good!";
elif [[ $scores -gt 60 ]]; then
echo "pass!";
else
echo "no pass!"
fi
- 輸入下方命令執行:
/bin/bash scores.sh
- 顯示:usage: {scores.sh 60|80.},說明不能爲空;
- 輸入: /bin/bash scores.sh 60 ->顯示: no pass!
- 輸入: /bin/bash scores.sh 61 ->顯示: pass!
- 輸入: /bin/bash scores.sh 100 ->顯示: very good!
說明這個腳本是能夠根據輸入進入的分數進行判斷是否合格,並給予分數對應的評價;
3.6 使用if條件語句編寫MySQL備份腳本
- 創建並編輯:
vi auto_backup_mysql.sh
- 內容如下:
#!/bin/bash
#auto bakcup mysql db
#by authors anyu 2019
#define backup path
BAK_DIR=/data/backup/`date +%Y%m%d`
MYSQLDB=discuz # 數據庫名
MYSQLUSR=root # 用戶名
MYSQLPW=123456 # 密碼
MYSQLCMD=/usr/bin/mysqldump
if [ $UID -ne 0 ];then
echo "Must to be use root for exec shell" # 必須使用Root用戶登錄
exit
fi
if [ ! -d $BAK_DIR ];then
mkdir -p $BAK_DIR
echo -e "\033[32mThe $BAK_DIR Create Successfully!"
else
echo "This $BAK_DIR is exists..."
fi
$MYSQLCMD -u$MYSQLUSR -p$MYSQLPW -d $MYSQLDB >$BAK_DIR/$MYSQLDB.sql
if [ $? -eq 0 ];then # 判斷是否執行成功
echo -e "\033[32mThe Mysql Backup $MYSQLDB Successfully!\033[0m"
else
echo -e "\033[32mThe Mysql Backup $MYSQLDB Failed,Please check.\033[0m"
fi
- 執行腳本:
sh -n auto_backup_mysql.sh
/bin/sh auto_backup_mysql.sh
- 加每天定時運行命令(定時任務):
crontab -e
- 增加的內容如下
0 0 * * * /bin/bash /data/shell/auto_backup_mysql.sh >>/tmp/mysql_bak.log
加入定時任務後,會按照時間表達式定時執行,如果已經備份過則無需再次備份,腳本內的if語句會自行判斷;
> `` 這個反引號會被解析爲命令,而單引號不會被解析;