循環 函數 軟件包 【中】
創建無限循環
while true; do
循環體
done
until false; do
循環體
Done
特殊用法
while循環的特殊用法(遍歷文件的每一行):
while read line; do
循環體
done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將 行賦值給變量line
示例
[root@localhost bin]# bash wenben.sh
#!
#
read -p "please input [yesno]:" a
case $a in
[yY]|[yY][eE][sS])
echo "the user input $a"
;;
[nN]|[nN][oO])
echo "the user input $a"
;;
*)
echo "eht user innput other"
;;
esac
[root@localhost bin]# cat wenben.sh
#/bin/bash
while read line
do
echo $line
done < uu.sh
[root@localhost bin]#
特殊用法之小括號
雙小括號方法,即((…))格式,也可以用於算術運算
雙小括號方法也可以使bash Shell實現C語言風格的變量操作
#I=10
#((I++))
for循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))
do
循環體
done
控制變量初始化:僅在運行到循環代碼段時執行一次 控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算 ,而後再做條件判斷
select 循環與菜單
select variable in list
do
循環體命令
done
select 循環主要用於創建菜單,按數字順序排列的 菜單項將顯示在標準錯誤上,並顯示 PS3 提示符, 等待用戶輸入 用戶輸入菜單列表中的某個數字,執行相應的命令
用戶輸入被保存在內置變量 REPLY 中。
select 與 case 一般是一起用的
select 是個無限循環,因此要記住用 break 命令退 出循環,或用 exit 命令終止腳本。也可以按 ctrl+c 退出循環。
select 經常和 case 聯合使用
與 for 循環類似,可以省略 in list ,此時使用位置 參量
函數介紹
1 函數function是由若干條shell命令組成的語句塊,實現代碼 重用和模塊化編程。
2 它與shell程序形式上是相似的,不同的是它不是一個單獨的 進程,不能獨立運行,而是shell程序的一部分。 3 函數和shell程序比較相似,區別在於:
4 Shell程序在子Shell中運行
5 而Shell函數在當前Shell中運行。因此在當前Shell中,函數可以 對shell中變量進行修改
函數由兩部分組成:函數名和函數體。
語法一:
function f_name {
...函數體...
}
語法二:
function f_name () {
...函數體...
}
語法三:
f_name (){
...函數體...
}
函數的定義和使用: 可在交互式環境下定義函數 可將函數放在腳本文件中作爲它的一部分 可放在只包含函數的單獨文件中
調用:函數只有被調用纔會執行;
調用:給定函數名 函數名出現的地方,會被自動替換爲函數代碼
函數的生命週期:被調用時創建,返回時終止
函數返回值
函數有兩種返回值: 函數的執行結果返回值:
(1) 使用echo或printf命令進行輸出
(2) 函數體中調用命令的輸出結果
函數的退出狀態碼:
(1) 默認取決於函數中執行的最後一條命令的退出狀態碼
(2) 自定義退出狀態碼,其格式爲:
return 從函數中返回,用最後狀態命令決定返回值
return 0 無錯誤返回。
return 1-255 有錯誤返回
交互式環境下定義和使用函數
例如:
$dir() {
> ls -l
> }
定義該函數後,若在$後面鍵入dir,其顯示結果同ls -l的 作用相同。
$dir
該dir函數將一直保留到用戶從系統退出,或執行了如下 所示的unset命令:
$ unset dir
在腳本中定義及使用函數
函數在使用前必須定義,因此應將函數定義放在腳本開始部分,直至 shell首次發現它後才能使用 調用函數僅使用其函數名即可。
例如:
$cat func1
#!/bin/bash
# func1 hello() {
echo "Hello there today's date is `date +%F`"
}
echo "now going to the function hello"
hello
echo "back from the function"
使用函數文件
1 可以將經常使用的函數存入函數文件,然後將函 數文件載入shell。
2 文件名可任意選取,但最好與相關任務有某種聯
3 一旦函數文件載入shell,就可以在命令行或腳本 中調用函數。可以使用set命令查看所有定義的函 數,其輸出列表包括已經載入shell的所有函數。
4 若要改動函數,首先用unset命令從shell中刪除 函數。改動完畢後,再重新載入此文件。
創建函數文件
函數文件示例:
$cat functions.main
#!/bin/bash
#functions.main findit() {
if [ $# -lt 1 ] ; then
echo "Usage:findit file" return 1
fi
find / -name $1 –print
}
載入函數
函數文件已創建好後,要將它載入shell
定位函數文件並載入shell的格式:
. filename 或 source filename
此即<點> <空格> <文件名> 這裏的文件名要帶正確路徑
上例中的函數,可使用如下命令: $ . functions.main
檢查載入函數
使用set命令檢查函數是否已載入。set命令將在shell中顯示 所有的載入函數。
示例:
$set findit=( ) {
if [ $# -lt 1 ]; then
echo "usage :findit file";
return 1
fi
find / -name $1 -print
} …
執行shell函數
要執行函數,簡單地鍵入函數名即可:
示例:
$findit groups
/usr/bin/groups
/usr/local/backups/groups.bak
刪除shell函數 現在對函數做一些改動。首先刪除函數,使其對shell不可用 。使用unset命令完成此功能. 命令格式爲:
unset function_name
實例:
$unset findit
再鍵入set命令,函數將不再顯示
函數參數
函數可以接受參數:
傳遞參數給函數:調用函數時,在函數名後面以空白分隔 給定參數列表即可;
例如“testfunc arg1 arg2 ...”
在函數體中當中,可使用$1, $2, ...調用這些參數;還 可以使用$@, $*, $#等特殊變量
函數變量
變量作用域:
環境變量:當前shell和子shell有效 本地變量:只在當前shell進程有效,爲執行腳本會啓動 專用子shell進程;因此,本地變量的作用範圍是當前shell腳本 程序文件,包括腳本中的函數。
局部變量:函數的生命週期;函數結束時變量被自動銷燬
注意:如果函數中有局部變量,如果其名稱同本地變量,使 用局部變量。
在函數中定義局部變量的方法 local NAME=VALUE
函數遞歸實例
函數遞歸:
函數直接或間接調用自身
注意遞歸層數
遞歸實例: 階乘是基斯頓·卡曼於 1808 年發明的運算符號,是數學術語 一個正整數的階乘(factorial)是所有小於及等於該數的正整 數的積,並且有0的階乘爲1。自然數n的階乘寫作n!。
n!=1×2×3×...×n。
階乘亦可以遞歸方式定義:0!=1,n!=(n-1)!×n。
n!=n(n-1)(n-2)...1
n(n-1)! = n(n-1)(n-2)!
示例:
fact.sh
#!/bin/bash
# fact() {
if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1 else echo $[$1*$(fact $[$1-1])]
fi
}
fact $1
軟件包管理
包查詢
rpm {-q|--query} [select-options] [query-options]
[select-options] -a: 所有包
-f: 查看指定的文件由哪個程序包安裝生成
-p rpmfile:針對尚未安裝的程序包文件做查詢操作;
--whatprovides CAPABILITY:查詢指定的CAPABILITY 由哪個包所提供
--whatrequires CAPABILITY:查詢指定的CAPABILITY被 哪個包所依賴
rpm2cpio 包文件|cpio –itv 預覽包內文件
rpm2cpio 包文件|cpio –id “*.conf” 釋放包內文件
[query-options]
--changelog:查詢rpm包的changelog
-c: 查詢程序的配置文件
-d: 查詢程序的文檔
-i: information -l: 查看指定的程序包安裝後生成的所有文件;
--scripts:程序包自帶的腳本片斷
-R: 查詢指定的程序包所依賴的CAPABILITY;
--provides: 列出指定程序包所提供的CAPABILITY
查詢用法:
-qi PACKAGE,
-qf FILE,
-qc PACKAGE,
-ql PACKAGE,
-qd PACKAGE
-qpi PACKAGE_FILE,
-qpl PACKAGE_FILE, ...
-qa
卸載:
rpm {-e|--erase}
[--allmatches]
[--nodeps]
[-noscripts]
[--notriggers]
[--test]
PACKAGE_NAME ...
包校驗
rpm {-V|--verify} [select-options] [verify-options]
S file Size differs
M Mode differs (includes permissions and file type)
5 digest (formerly MD5 sum) differs
D Device major/minor number mismatch
L readLink(2) path mismatch
U User ownership differs
G Group ownership differs
T mTime differs
P capabilities differ
包來源合法性驗正及完整性驗正:
完整性驗正:SHA256
來源合法性驗正:RSA
公鑰加密:
對稱加密:加密、解密使用同一密鑰;
非對稱加密:密鑰是成對兒的
public key: 公鑰,公開所有人
secret key: 私鑰, 不能公開
導入所需要公鑰:
rpm -K|checksig rpmfile 檢查包的完整性和簽名
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
CentOS 7發行版光盤提供:RPM-GPG-KEY-CentOS-7
rpm -qa gpg-pubkey*
rpm數據庫
數據庫重建: /var/lib/rpm rpm {--initdb|--rebuilddb}
initdb: 初始化
如果事先不存在數據庫,則新建之 否則,不執行任何操作
rebuilddb:重建
無論當前存在與否,直接重新創建數據庫
yum
CentOS: yum, dnf
YUM: Yellowdog Update
1 Modifier,rpm的前端程序,用來解決軟件包相關依賴性,可以在多個庫之間定位軟件包,
2 up2date的替代工具 yum repository: yum repo,存儲了衆多rpm包,以及 包的相關的元數據文件(放置於特定目錄repodata下)
文件服務器:
ftp://
http://
file:///
yum配置文件
yum客戶端配置文件:
/etc/yum.conf:爲所有倉庫提供公共配置
/etc/yum.repos.d/*.repo:爲倉庫的指向提供配置
倉庫指向的定義:
[repositoryID]
name=Some name for this repository
baseurl=url://path/to/repository/
enabled={1|0}
gpgcheck={1|0}
gpgkey=URL
enablegroups={1|0}
failovermethod={roundrobin|priority}
默認爲:roundrobin,意爲隨機挑選;
cost= 默認爲1000
用循環 顯示一個等腰三角形
root@localhost bin]# chmod a+x sanjiaooo.sh
[root@localhost bin]# sanjiaooo.sh
please enter a number:10
#
###
#####
#######
#########
###########
#############
###############
#################
###################
[root@localhost bin]# cat sanjiaooo.sh
#!/bin/bash
#
read -p "please enter a number:" n
for k in `seq $n`;do
for j in `seq $[$n-$k]`;do
echo -n " "
done
i=$[$k*2-1]
for l in `seq $i`;do
echo -n "#"
done
echo
done
[root@localhost bin]#
用select和case 做個簡易菜單
[root@localhost bin]# caidan.sh
1) gongbaojiding 3) baoyu 5) xie
2) hongshaorou 4) dayu 6) xia
how do you like?1
10 yuan
[root@localhost bin]# caidan.sh
1) gongbaojiding 3) baoyu 5) xie
2) hongshaorou 4) dayu 6) xia
how do you like?3
100yuan
[root@localhost bin]# cat caidan.sh
#!/bin/bash
#
PS3="how do you like?"
select caidan in gongbaojiding hongshaorou baoyu dayu xie xia
do
case $caidan in
gongbaojiding)
echo "10 yuan"
break
;;
hongshaorou)
echo "20 yuan"
break
;;
baoyu)
echo "100yuan"
break
;;
dayu)
echo "40 yuan"
break
;;
xie)
echo "88 yuan "
break
;;
xia)
echo "99 yuan "
break
;;
*)
echo "no exist"
break
esac
done
[root@localhost bin]#
漢諾塔 遊戲
[root@localhost bin]# hannuotao.sh
please input the number you want:3
move 1: A-->C
move 2: A-->B
move 1: C-->B
move 3: A-->C
move 1: B-->A
move 2: B-->C
move 1: A-->C
[root@localhost bin]# cat hannuotao.sh
#!/bin/bash
read -p "please input the number you want:" n
a="A"
b="B"
c="C"
game(){
if [ $1 -eq 1 ];then
echo "move $1: $2-->$4"
else
game $[$1-1] $2 $4 $3
echo "move $1: $2-->$4"
game $[$1-1] $3 $2 $4
fi
}
game $n $a $b $c