1. 程式人生 > >Shell腳本基礎 、 使用變量 、 條件測試及選擇 、 列表式循環

Shell腳本基礎 、 使用變量 、 條件測試及選擇 、 列表式循環

shell腳本基礎 、 使用變量 、 條件測試及選擇 、 列表式循環

##################################################################################################
shell腳本:
腳本:可以執行的文件,運行之後實現某種功能(命令的堆積,交互式)

規範shell腳本的一般組成:
#! 環境聲明
# 註釋文本
可執行代碼

###############################################################################################
一。書寫第一個腳本程序
#vim /root/1.sh
#! /bin/bash

echo "hello world" //輸出hello world
hostname //輸出主機名
ifconfig | head -2 //輸出網卡信息前兩行
cat /etc/redhat-release //輸出系統版本信息
#chmod +x /root/1.sh //賦予文件執行權限
#/root/1.sh //執行腳本程序
hello word
server0.example.com
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.0.11 netmask 255.255.255.0 broadcast 172.25.0.255
Red Hat Enterprise Linux Server release 7.0 (Maipo) //輸出結果

##################################################################################################

二。書寫為server0自動搭建yum的腳本
#vim /root/yum.sh //創建腳本程序文件
#! /bin/bash
echo ‘[rhel] //yum倉庫信息
name=rhel //yum倉庫名稱
baseurl=http://172.25.254.254/content/rhel7.0/x86_64/dvd/ //網絡yum源地址
enable=1 //開機自動加載
gpgcheck=0‘ > /etc/yum.repos.d/rhel.repo //不進行簽名認證,將這些內容重定向輸出到文件/etc/yum.repos.d/rhel.repo
#yum clean all //清空緩存
#yum repolist //查看yum軟件包信息
#chmod +x /root/yum.sh //賦予執行權限
#/root/yum.sh //執行腳本程序已加載插件:langpacks
正在清理軟件源: rhel
Cleaning up everything
已加載插件:langpacks
rhel | 4.1 kB 00:00
(1/2): rhel/group_gz | 134 kB 00:00
(2/2): rhel/primary_db | 3.4 MB 00:00
源標識 源名稱 狀態
rhel rhel 4,305
repolist: 4,305 //運行成功


###############################################################################################################

管道傳遞:
管道操作:將上一條命令的標準輸出交由下一條命令進行處理。

免交互及輸出處理:
免交互處理: 腳本一般在後臺進行,要減少人工交互的語句

腳本輸出信息處理:
記錄有價值的信息(>> /var/log/foo.log)
屏蔽無價值的,幹擾的信息(&> /dev/null)
用戶自定義輸出:echo ‘文本字符串’

重定向輸出:
標準輸出:命令執行正常是顯示結果
標準錯誤:命令執行出錯或異常時顯示結果

將屏幕信息保存到文件:
> 將正確輸出收集到文件當中
2> 將錯誤輸出收集到文件當中
&> 收集前面命令的正確和錯誤輸出
>&2 將命令的正確輸出改為錯誤輸出

# echo 123 > /opt/a.txt
# cat /opt/a.txt /etc
123 //正確輸出
cat: /etc: 是一個目錄 //錯誤輸出
# cat /opt/a.txt /etc > /opt/b.txt //只收集正確輸出
cat: /etc: 是一個目錄
# cat /opt/a.txt /etc 2> /opt/b.txt //只收集錯誤輸出
123
# cat /opt/a.txt /etc &> /opt/b.txt //正確與錯誤輸出全都收集

#################################################################################################################

三。書寫創建用戶並設置密碼的腳本:
# vim /root/user.sh

#!/bin/bash
useradd test06 &> /dev/null
echo test06創建成功
echo 123 | passwd --stdin test06 &> /dev/null
echo test06密碼設置成功

# chmod +x /root/user.sh
# /root/user.sh

#################################################################################################################

變量:為了增加腳本適應環境的能力,增加腳本的靈活度,方便。
變量:相當於容器,以不變的名稱,儲存變化的值。
變量名=變化的值

使用變量: $變量名


為了降低腳本使用難度,可以產生交互
read :可以產生交互,將鍵盤輸入的內容賦值給變量

#vim /root/user.sh
read -p "請輸入您要創建的用戶:" user //user為用戶名變量
read -p "請輸入您要設置的密碼:" pass //pass為用戶密碼變量
useradd $user &> /dev/null //正確與錯誤信息全都收集在/dev/null
echo $user 創建成功
echo $pass | passwd --stdin $user &> /dev/null
echo $user 密碼設置成功
#/root/user.sh
請輸入您要創建的用戶:lala
請輸入您要設置的密碼:12
lala 創建成功
lala 密碼設置成功

#######################################################################

什麽是變量
以不變的名稱存放的可能會變化的值
– 變量名=變量值
– 方便以固定名稱重復使用某個值
– 提高對任務需求、運行環境變化的適應能力


設置變量時的註意事項
– 若指定的變量名已存在,相當於為此變量重新賦值
– 等號兩邊不要有空格
– 變量名由字母/數字/下劃線組成,區分大小寫
– 變量名不能以數字開頭,不要使用關鍵字和特殊字符


基本格式
– 引用變量值:$變量名
– 查看變量值:echo $變量名、echo ${變量名}


變量的種類



位置變量
在執行腳本時提供的命令行參數(非交互式傳值)

[root@server0 ~]# vim /root/2.sh
#!/bin/bash
echo $1
echo $2
echo $3
echo ${10}
echo ${11}

# /root/2.sh haha benniu xixi hehe lele dc tc dz tz 100 200

[root@server0 ~]# vim /root/3.sh
#!/bin/bash
cat -n $1 | head -$2

[root@server0 ~]# /root/3.sh /etc/passwd 2
[root@server0 ~]# /root/3.sh /etc/passwd 3



預定義變量
用來保存腳本程序的執行信息
– 直接使用這些變量
– 不能直接為這些變量賦值

$# 已加載的位置變量的個數
$* 所有位置變量的值
$? 程序退出後的狀態值,0表示正常,其他值異常



[root@server0 ~]# vim /root/2.sh

#!/bin/bash
echo $1
echo $2
echo $3
echo ${10}
echo ${11}
echo $#
echo $*

[root@server0 ~]# /root/2.sh 1 2 3 4 5 6 7 8 9 10 11


########################################################
運算

[root@server0 ~]# expr 10 / 3

[root@server0 ~]# expr 10 \* 3

[root@server0 ~]# expr 1 + 2

[root@server0 ~]# expr 3 - 1

[root@server0 ~]# expr 10 % 3 #取余數 運算

$() :將命令的輸出結果,作為參數

[root@server0 opt]# date
[root@server0 opt]# date +%F
[root@server0 opt]# cd /opt

[root@server0 opt]# mkdir $(date +%F)
[root@server0 opt]# ls
[root@server0 opt]# mkdir mydir-$(date +%F)
[root@server0 opt]# ls
[root@server0 opt]# mkdir MariaDB-$(date +%F)
[root@server0 opt]# ls
[root@server0 opt]# mkdir $(hostname)-$(date +%F)

#######################################################
常用的測試選項

檢查文件狀態
-e:文檔存在為真
-d:文檔存在且為目錄為真
-f:文檔存在且為文件為真
-r:文檔存在且有讀取權限為真
-w:文檔存在且有寫入權限為真
-x:文檔存在且有執行權限為真

比較整數大小(帶e都有等於二字,g代表大於,l代表小於)

-gt:大於
-ge:大於等於
-eq:等於
-ne:不等於
-lt:小於
-le:小於等於

字符串比對
== :相等
!=:不相等


########################################################



if [ 條件測試 ] ; then
命令序列xx
else
命令序列yy
fi

[root@server0 /]# vim /root/5.sh
#!/bin/bash
if [ $1 -eq $2 ];then
echo hello
else
echo hi
fi

[root@server0 /]# /root/5.sh 1 1

[root@server0 /]# /root/5.sh 1 2

###########################################################################################################

請書寫一個腳本:
用戶輸入一個IP地址(read),判斷是否可以與該IP地址通信,
能通則輸出 "IP ok" 否則 輸出 "IP no"

[root@server0 /]# vim /root/6.sh

#!/bin/bash
read -p ‘請輸入一個IP地址:‘ ip
ping -c 2 $ip &> /dev/null

if [ $? -eq 0 ];then
echo ${ip} ok
else
echo ${ip} no
fi

[root@server0 /]# /root/6.sh

##########################################################################################

if [條件測試1] ; then
命令序列xx
elif [條件測試2] ; then
命令序列yy
else
命令序列zz
fi


成績 大於等於90 優秀
大於等於80 良好
大於等於70 及格
大於等於60 仍需努力
60以下 在牛的肖邦,也彈不出哥憂傷




[root@server0 ~]# vim /root/8.sh
#!/bin/bash
read -p ‘請輸入您的成績:‘ num
if [ $num -gt 100 ];then
echo 成績有誤
elif [ $num -lt 0 ];then
echo 成績有誤
elif [ $num -ge 90 ];then
echo 優秀
elif [ $num -ge 80 ];then
echo 良好
elif [ $num -ge 70 ];then
echo 及格
elif [ $num -ge 60 ];then
echo 仍需努力
else
echo 在牛的肖邦,也彈不出哥憂傷
fi

############################################################################################################3

在 server0 上創建 /root/foo.sh 腳本
1)當運行/root/foo.sh redhat,輸出為fedora
2)當運行/root/foo.sh fedora,輸出為redhat
3)當沒有任何參數或者參數不是 redhat 或者
fedora時,其錯誤輸出產生以下信息:
/root/foo.sh redhat|fedora







‘ ‘:把所有的特殊字符,當作普通文本字符輸出

[root@server0 ~]# vim /root/foo.sh
#!/bin/bash
if [ $1 == redhat ];then
echo fedora
elif [ $1 == fedora ];then
echo redhat
else
echo ‘/root/foo.sh redhat|fedora‘
fi

[root@server0 ~]# /root/foo.sh redhat
[root@server0 ~]# /root/foo.sh fedora

[root@server0 ~]# /root/foo.sh haha

存在的問題:當用戶不輸入任何參數時,表達式不成立;因為$1沒有,所以表達式if [ $1 == redhat ];then,就相當於if [ == redhat ];then,相當於redhet在和一個不存在變量在比較;所以表達式不成立。



#!/bin/bash
if [ $# -eq 0 ];then
echo ‘/root/foo.sh redhat|fedora‘
elif [ $1 == redhat ];then
echo fedora
elif [ $1 == fedora ];then
echo redhat
else
echo ‘/root/foo.sh redhat|fedora‘
fi

存在問題:題中表示其錯誤輸出表示為:/root/foo.sh redhat|fedora。但是,在我們運行此腳本,root/foo.sh redhat|fedora為正確輸出,所以我們要將root/foo.sh redhat|fedora變為錯誤輸出。

>&2 #將正確輸出變成錯誤
" ":可以將 “沒有” 變成 “ 空值”


#!/bin/bash

if [ "$1" == redhat ];then
echo fedora
elif [ "$1" == fedora ];then
echo redhat
else
echo ‘/root/foo.sh redhat|fedora‘ >&2 #將正確輸出變成錯誤
exit 2 #腳本退出返回值
fi

解釋:當用戶不輸入任何參數時,表達式[ "$1" == redhat ],相當於[ " " == redhat ]。表示一個空值,所以不相等,所以輸出/root/foo.sh redhat|fedora

################################################################################################################


for循環結構

循環結構:將反復執行的語句,循環去執行


for 變量名 in 值列表
do
命令序列
done




[root@server0 /]# vim /root/for.sh
#!/bin/bash
for a in 1 2 3 4 5
do
useradd nsd$a
echo nsd$a創建成功
done

[root@server0 /]# vim /root/for02.sh
#!/bin/bash
for a in 1 2 3 4 5
do
echo hello
done

##################################################################################################################

案例5:編寫一個批量添加用戶腳本
在 server0 上創建 /root/batchusers 腳本
1)此腳本要求提供用戶名列表文件作為參數
2)如果沒有提供參數,此腳本應該給出提示
Usage: /root/batchusers,退出並返回相應值
3)如果提供一個不存在的文件,此腳本應該給出提
示 Input file not found,退出並返回相應值
4)新用戶的登錄Shell為 /bin/false,無需設置密碼
5)用戶列表測試文件:
http://classroom/pub/materials/userlist


# wget http://classroom/pub/materials/userlist

[root@server0 /]# vim /root/batchusers
#!/bin/bash
if [ $# -eq 0 ];then //$#位置變量的數量,當不提供參數時,$#為0,表達式成立
echo ‘Usage: /root/batchusers‘ >&2 //輸出Usage: /root/batchusers >&2 變為錯誤輸出
exit 1 //返回值為1,提示輸入參數有誤
elif [ ! -f $1 ];then
echo ‘Input file not found‘ >&2
exit 2
fi
for a in $(cat $1)
do
useradd -s /bin/false $a
echo $a創建成功
done

##################################################



#!/bin/bash
if [ $# -eq 0 ];then
echo ‘Usage: /root/batchusers‘ >&2
exit 1
elif [ -e $1 ];then
for a in $(cat $1)
do
useradd -s /bin/false $a
echo $a創建成功
done
else
echo ‘Input file not found‘ >&2
exit 2
fi

###################################################

Shell腳本基礎 、 使用變量 、 條件測試及選擇 、 列表式循環