shell 01
shell 翻譯官
shell腳本 工具,提高工作效率
命令 交互式
腳本 非交互式
cat /etc/shells 查看擁有的解釋器
yum -y install ksh 安裝新解釋器
bash優點 歷史命令,快捷鍵,tab鍵,重定向,管道
腳本的格式:
1,聲明解釋器類型
#!/bin/bash
2,註釋,說明該腳本的作用,變量的含義等
3,編寫代碼
寫完後,賦予腳本執行權限 chmod +x test1.sh
執行腳本的方法:
1, ./test1.sh 使用絕對路徑或者相對路徑執行腳本 ,需要x權限
2, bash test1.sh 調用另外一個bash執行腳本,開啓子進程
3, source test1.sh 使用當前解釋器執行腳本,不開啓子進程
#!/bin/bash
mkdir /opt/abc
cd /opt/abc
#!/bin/bash
echo 123
sleep 1000
#!/bin/bash
#部署yum軟件倉庫
rm -rf /etc/yum.repos.d/*.repo
echo "[abc]
name=abc
baseurl=http://172.25.254.254/content/rhel7.0/x86_64/dvd/
enabled=1
gpgcheck=0" > /etc/yum.repos.d/abc.repo
#!/bin/bash
#部署vsftpd服務
yum -y install vsftpd &> /dev/null
systemctl restart vsftpd
systemctl enable vsftpd
==============================
常量 固定不變
變量 靈活多變,增加靈活,增加功能
變量的種類
1,自定義變量
變量名稱=變量的值 名稱必須是字母數字下劃線,不能以數字開頭,不能使用特殊符號
a=10 定義變量
echo $a 查看變量的值
echo ${a}RMB 輸出變量+常量,大括號用來界定容易混淆的名稱
unset a 取消變量
echo $a 再次查看
2,環境變量,系統自帶
USER當前用戶名 UID當前用戶的id號 HOME當前用戶的家目錄 PWD當前位置 SHELL當前用戶使用的解釋器 HOSTNAME主機名
PS1一級提示符 PS2二級提示符 PATH存放命令的路徑
echo $PS1 顯示一級提示符
[\u@\h \W]\$
PS1=dachui 修改
PS1='[\u@\h \W]\$' 還原
3,位置變量與預定義變量
$1 $2 $3 .....
$0腳本名 $$進程號 $#位置變量的個數 $*所有的位置變量 $?上一條指令的結果,0是成功, 非0是失敗
env 查看所有環境變量
set 查看所有變量
變量的擴展應用
"" 界定範圍
'' 界定範圍,屏蔽特殊符號
touch "a b" 創建一個帶空格文件
touch 'x y' 創建一個帶空格文件
a=10
echo "$a" 顯示變量a中的值
echo '$a' 顯示$a
`` 反撇號, 可以獲取命令的執行結果
a=ls 變量a的值是ls
a=`ls` 變量a的值是ls執行的結果
a=$(ls) 變量a的值是ls執行的結果
stty -echo 屏蔽回顯
stty echo 恢復回顯
a=100 通常創建的變量是局部變量 ,只在某個解釋器中生效
export 發佈全局變量,使任何解釋器(子進程中均可使用)
a=100
export a 將a發佈爲全局變量
export b=200 創建併發布全局變量
bash 進入新解釋器(子進程)
echo $a 可以使用之前發佈的變量
echo $b
exit 返回
export -n b 取消變量b的全局狀態,恢復爲局部變量
===============================
shell中的運算
方法一:
expr 1 + 1 加
expr 2 - 1 減
expr 2 \* 2 乘 \ 轉義符號 ,可以屏蔽之後1個字符的特殊含義
expr 4 / 2 除
expr 4 % 2 求模(取餘數)
a=10
b=20
expr $a + $b
expr $a + 10
expr $a + $a
方法二:
echo $[1+1]
echo $[2-1]
echo $[2*2]
echo $[2/2]
echo $[2%2]
echo $[a+b]
echo $[a+20]
方法三: let 運算結果不顯示, 通常用於變量創建或者變量自增減
let a=5+5 創建變量a
變量自增減
主流寫法:
let a-- 相當於 let a=a-1
let a++ 相當於 let a=a+1
let a+=2 相當於 let a=a+2
let a-=2 相當於 let a=a-2
let a/=5 相當於 let a=a/5
let a*=4 相當於 let a=a*4
let a%=4 相當於 let a=a%4
bc 計算器 ,可以小數運算
echo "scale=3;10/3" | bc
sell 02
回顧
shell
/bin/bash 歷史記錄,快捷鍵,tab鍵,重定向,管道
規範的shell腳本:
聲明解釋器 #!/bin/bash
註釋,腳本功能,變量的作用
代碼
腳本的執行方式:
1,添加x權限
2,調用解釋器直接執行 bash XXX.sh
3,source XXX.sh
變量:
1, 自定義變量 變量名=變量的值
echo ${a}XXX
unset a
2,環境變量 USER UID HOME HOSTNAME SHELL PWD PS1 PS2 PATH
3,位置變量與預定義變量
$1 $2 $3..... $0 $$ $# $* $?
變量擴展:
"" ''
` $()
read -p "XXX" n
stty -echo stty echo
export a 發佈全局變量
運算:
expr 1 + 1
echo $[1+1]
let a=10+3 let a++ let a*=10
bc
=================================
條件測試,可以讓腳本更智能的工具
1,字符串的測試 == 判斷兩邊的內容是否相等 !=
[ a == a ] a是否等於a
echo $? 結果是0
[ a == b ]
echo $? 結果非0
[ root == $USER ] 我是不是管理員,結果是0
su - abc 切換普通用戶之後在測試,結果非0
a=10
b=
[ -n "$a" ] 判斷$a是否非空
echo $?
[ -n "$b" ] 判斷$b是否非空
echo $?
[ ! -n "$b" ] 上述判斷取反,判斷$b是否爲空
echo $?
[ -z "$a" ] 判斷$a是否爲空
echo $?
[ -z "$b" ] 判斷$b是否爲空
4, 邏輯測試
&& 符號之前的任務成功後,才執行之後的任務
|| 符號之前的任務失敗後,才執行之後的任務
ls && ls 第一個任務成功了,會繼續執行第2個任務, 一共執行兩次ls
ls || ls 第一個任務成功了,不會繼續執行第2個任務, 一共執行1次ls
[ -z $1 ] && exit 如果$1爲空, 就會執行exit退出腳本
兩個邏輯符號: 在ls都執行成功的情況下
ls && ls && ls 執行3次ls
ls && ls || ls 第1次執行,第2次執行,第3次不執行
ls || ls || ls 第1次執行,後面都不執行
ls || ls && ls 第1次執行,第2次不執行,第3次執行
[ root == $USER ] && echo "我是管理員" || echo "我不是管理員"
2,數字的測試
-eq等於 -ne不等於 -gt大於 -ge大於等於 -lt小於 -le小於等於
[ 1 -eq 1 ] 1等於1, echo $? 結果是成功
[ 0 -eq $USER ] 我的id號是否爲0,管理員運行的話,結果是成功
兩種不同寫法,可以實現相同目的:
[ -z $n ] && echo "你倒是給個名字啊!" && exit
[ -n "$n" ] || echo "你倒是給個名字啊!"
[ -n "$n" ] || exit
要求,每2分鐘檢查系統登錄賬戶數量,如果超過3人登錄,給管理員發報警郵件
#!/bin/bash
x=`who | wc -l`
[ $x -gt 3 ] && echo "有人***服務器!隔壁老王來了!" | mail -s test root
mail 查郵件
crontab -e
*/2 * * * * /opt/test1.sh
chmod +x test1.sh
3,文件的測試
-e 是否存在 -f 是否存在且爲普通文件 -d 是否存在且爲目錄
-r -w -x 判斷當前用戶對某文件是否有相關權限
[ -e abc ] abc是否存在,不關心文件類型
[ -f abc ] abc是否存在,必須是文件
[ -d abc ] abc是否存在,必須是目錄
[ -r abc ] 當前用戶對文件abc是否有讀權限,管理員無效
[ -w abc ] 當前用戶對文件abc是否有寫權限,管理員無效
[ -x abc ] 當前用戶對文件abc是否有執行(目錄是進入的)權限
================================
== != -z -n
-eq -ne -gt -ge -lt -le
-e -f -d -r -w -x
&& || ;
if判斷
種類1:
單分支
if 條件測試 ;then
執行指令
fi
#!/bin/bash
if [ ! -d /opt/xyz ] ;then
mkdir /opt/xyz
echo 123
fi
雙分支
if 條件測試 ;then
執行指令1
else
執行指令2 判斷當前目錄是否有a目錄,沒有就創建
fi
#!/bin/bash
if [ -f a ] ;then
rm -rf a
mkdir a
else
[ -d a ] || mkdir a
fi
多分支
if 條件測試1 ;then
執行指令1
elif 添加測試2 ;then
執行指令2
else
執行指令3
fi
============================
ping -c 檢測次數 -i 間隔時間(秒) -W 網絡無法通訊時的反饋時間
ping -c 3 -i 0.2 -W 1 172.25.0.13
#!/bin/bash
read -p "請輸入ip地址" ip
ping -c 3 -i 0.2 -W 1 $ip &> /dev/null
if [ $? -eq 0 ] ;then
echo "通了!"
else
echo "不通!"
fi
#!/bin/bash
x=$[RANDOM%10]
read -p "請輸入一個數字(0-9)" n
if [ $x -eq $n ] ;then
echo "猜中了!"
elif [ $n -lt $x ] ;then
echo "猜小了"
else
echo "猜大了"
fi
========================
循環
for循環 有次數限制 可以關注循環次數或者變量
for 變量名 in 值1 值2 值3......
do
執行指令
done
!/bin/bash```
for i in {1..10} 循環10次,此方式不支持變量比如{1..$a}
do
echo 123
echo $i
done
#!/bin/bash
a=10
for i in `seq $a` 使用變量循環10次
do
echo 123
echo $i
done
172.25.0.1~172.25.0.15
#!/bin/bash
for i in {1..15}
do
ping -c 3 -i 0.2 -W 1 172.25.0.$i &> /dev/null
if [ $? -eq 0 ] ;then
echo "172.25.0.$i 通了"
else
echo "172.25.0.$i 不通"
fi
done
#!/bin/bash
x=0
y=0
for i in {1..15}
do
ping -c 3 -i 0.2 -W 1 172.25.0.$i &> /dev/null
if [ $? -eq 0 ] ;then
echo "172.25.0.$i 通了"
let x++
else
echo "172.25.0.$i 不通"
let y++
fi
done
echo "$x臺通了,$y臺不通"
shell 03
回顧
條件測試
test 表達式 [ 表達式 ]
1,字符串 == != -n -z
2,邏輯測試 && || ;
3,數字 -eq -ne -gt -ge -lt -le
4,文件 -e -d -f -r -w -x
if 單分支 雙分支 多分支
if 條件測試1 ;then
執行指令1
elif 條件測試2 ;then
執行指令2
else
執行指令n
fi
循環
for 變量名稱 in 值
do
執行指令
done
while :
do
執行指令
done
ping -c -i -W
RANDOM
200行
===========================
case分支 ,功能類似if,不如if強大,代碼比if精簡
case 變量名稱 in
模式1)
執行指令1 ;;
模式2)
執行指令2 ;;
*)
執行指令n
esac
#!/bin/bash
case $1 in
t|T)
touch $2;;
m|M|mm)
mkdir $2
echo 123;;
r)
rm -rf $2;;
*)
echo "請輸入t|m|r"
esac
部署nginx服務
真實主機中:
scp lnmp_soft.tar.gz root@server0:/opt
虛擬機中:
在虛擬機中釋放該目錄,並將其中的nginx-1.10.3.tar.gz拷貝到/opt下
#!/bin/bash
yum -y install gcc openssl-devel pcre-devel &> /dev/null
tar -xf nginx-1.10.3.tar.gz
cd nginx-1.10.3
./configure
make
make install
執行完腳本後運行 /usr/local/nginx/sbin/nginx
關閉防火牆 systemctl stop firewalld
使用真機瀏覽器訪問172.25.0.11可以看到歡迎頁面
echo -e "\033[92mABCD\033[0m"
函數,能夠將公共的語句塊存儲在一個變量中,達到精簡腳本的目的
函數名稱 (){
指令
}
cecho (){
echo -e "\033[$1m$2\033[0m"
}
中斷和退出
exit 退出腳本
break 退出循環,繼續執行循環之後的任務
continue 退出當前循環,繼續下一次循環
從鍵盤循環取整數(0結束)並求和,輸出最終結果
#!/bin/bash
x=0
while :
do
read -p "請輸入一個數字" n
[ -z $n ] && exit
[ $n -eq 0 ] && break
let x+=n
done
echo $x
找出1~20以內6的倍數,並輸出她的平方值
#!/bin/bash
for i in {1..20}
do
x=$[i%6] x是餘數
[ $x -eq 0 ] || continue 餘數等於0就繼續下面的任務
echo $[i*i]
done
===============================
字符串處理
1,字符串的截取,第一個字符系統定義序號是0
${變量名:起始位置:長度}
echo ${a:1:1} 截取變量a,從第2個字符向後符截取1位
echo ${a:4:2} 截取變量a,從第5個字符向後符截取2位
echo ${a:0:2} 截取變量a,從第1個字符向後符截取2位 ,且0可以省略
獲取一位隨機字符的腳本:
#!/bin/bash
a=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV
WXYZ0123456789
x=$[RANDOM%62]
echo ${a:x:1}
獲取8爲隨機密碼的腳本:
#!/bin/bash
a=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV
WXYZ0123456789
for i in {1..8}
do
x=$[RANDOM%62]
p=${a:x:1}
pa=$pa$p
done
echo $pa
2 字符串的替換
a=aabbccdd
${變量名/old/new} 替換一個old爲new
${變量名/a/6} a換成6
${變量名//old/new} 替換所有old爲new
${變量名//a/6} 所有a換成6
${變量名/old/} 刪除一個old
${變量名//old/} 刪除所有old
3,字符串的刪除
${變量名#被刪除的內容} 掐頭
a=`head -1 /etc/passwd`
echo $a
root:x:0:0:root:/root:/bin/bash
echo ${a#root} 刪除第一個root
echo ${a#root:x} 刪除root:x
echo ${a##*root} 刪除到最後一個root,以及該root左邊所有
思考如何刪除之後剩餘 echo ${a#*:root:}
/root:/bin/bash
${變量名%被刪除的內容} 去尾
echo ${a%bash} 從右往左刪除,到bash
echo ${a%%/*} 從右往左刪除,到最後一個/ ,以及/右邊所有