bash進階學習ing

使用read命令來接受輸入
使用read來把輸入值分配給一個或多個shell變量:

  • -p 指定要顯示的提示

  • -t TIMEOUT

read 從標準輸入中讀取值,給每個單詞分配一個變量
所有剩余單詞都被分配給最后一個變量
read -p “Enter a filename: “ FILE

條件選擇if語句
選擇執行:
注意: if語句可嵌套
單分支
if 判斷條件: then
條件為真的分支代碼
fi
雙分支
if 判斷條件; then
條件為真的分支代碼
else
條件為假的分支代碼
fi40
if 語句
多分支

if CONDITION1; then
if-true
elif CONDITION2; then
if-ture
elif CONDITION3; then
if-ture

else
all-false
fi

逐條件進行判斷,第一次遇為“真”條件時,執行其分支,
而后結束整個if語句41
if實例
根據命令的退出狀態來執行命令
if ping -c1 -W2 station1 &> /dev/null; then
echo ‘Station1 is UP’
elif grep “station1” ~/maintenance.txt &> /dev/null
then
echo ‘Station1 is undergoing maintenance‘
else
echo ‘Station1 is unexpectedly DOWN!’
exit 1
fi

條件判斷: case語句

case 變量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;

*)
默認分支
;;
esac

case支持glob風格的通配符:
*: 任意長度任意字符
?: 任意單個字符
[]:指定范圍內的任意單個字符
a|b: a或b43
練習
1、寫一個腳本/root/bin/createuser.sh,實現如下功能:使用一個用戶名做為參數,如果指定參數的用戶存在,就顯示其存在,否則添加之;顯示添加的用戶的id號等信息

201608201639001
2、寫一個腳本/root/bin/yesorno.sh,提示用戶輸入yes或no,并判斷用戶輸入的是yes還是no,或是其它信息

201608201640001
3、寫一個腳本/root/bin/filetype.sh,判斷用戶輸入文件路徑,顯示其文件類型(普通,目錄,鏈接,其它文件類型)

201608201640002
4、寫一個腳本/root/bin/checkint.sh,判斷用戶輸入的參數是否為正整數

201608201642001

循環

將某代碼段重復運行多次
重復運行多少次:
循環次數事先已知
循環次數事先未知
有進入條件和退出條件
for, while, until45
for循環
for 變量名 in 列表;do
循環體
done
執行機制:
依次將列表中的元素賦值給“變量名” ; 每次賦值后即執
行一次循環體; 直到列表中的元素耗盡,循環結束46
for循環
列表生成方式:
(1) 直接給出列表
(2) 整數列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令
$(COMMAND)
(4) 使用glob, 如: *.sh
(5) 變量引用;
$@, $*47
練習:用for實現
1、判斷/var/目錄下所有文件的類型

201608201710001
2、 添加10個用戶user1-user10,密碼同用戶名

201608201718001
3、 /etc/rc.d/rc3.d目錄下分別有多個以K開頭和以S開頭的
文件;分別讀取每個文件,以K開頭的文件輸出為文件加stop
,以S開頭的文件輸出為文件名加start;
“ K34filename stop”
“S66filename start”

201608201746001
4、寫一個腳本,提示輸入正整數n的值,計算1+2+3+…n的總和

201608201755001
5、 寫一個腳本,提示請輸入網絡地址,如192.168.0.0,判斷輸入的網段中主機在線狀態
6、 打印九九乘法表48
while循環
while CONDITION; do
循環體
done
CONDITION:循環控制條件;進入循環之前,先做一次判
斷;每一次循環之后會再次做判斷;條件為“ true”,則執行
一次循環;直到條件測試狀態為“ false”終止循環
因此: CONDTION一般應該有循環控制變量;而此變量的值
會在循環體不斷地被修正
進入條件: CONDITION為true;
退出條件: CONDITION為false49
練習:用while實現
1、求100以內所有正整數之和
2、通過ping命令探測172.16.250.1-254范圍內的所有主機
的在線狀態,統計在線主機和離線主機各多少。
3、打印九九乘法表
4、利用變量RANDOM生成10個隨機數字,輸出這個10數字
,并顯示其中的最大者和最小者
5、打印國際象棋棋盤50
until循環
until CONDITION; do
循環體
done
進入條件: CONDITION 為false
退出條件: CONDITION 為true51
循環控制語句continue
用于循環體中
continue [N]:提前結束第N層的本輪循環,而直接進入下一
輪判斷;最內層為第1層
while CONDTIITON1; do
CMD1

if CONDITION2; then
continue
fi
CMDn

done52
循環控制語句break
用于循環體中
break [N]:提前結束第N層循環, 最內層為第1層
while CONDTIITON1; do
CMD1

if CONDITION2; then
break
fi
CMDn

done53
創建無限循環
while true; do
循環體
done
until false; do
循環體
Done54
練習
1、每隔3秒鐘到系統上獲取已經登錄的用戶的信息;如果發
現用戶hacker登錄,則將登錄時間和主機記錄于日志

/var/log/login.log中,并提示該用戶退出系統。201608201821001
2、隨機生成10以內的數字,實現猜字游戲,提示比較大或小,相等則退出。

201608201831001
特殊用法
while循環的特殊用法(遍歷文件的每一行):
while read line; do
循環體
done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將
行賦值給變量line
練習
掃描/etc/passwd文件每一行,如發現GECOS字段為空,則填
充用戶名和單位電話為62985600,并提示該用戶的GECOS信
息修改成功.

201608201955001

201608201956001
特殊用法
雙小括號方法,即((…))格式,也可以用于算術運算
雙小括號方法也可以使bash Shell實現C語言風格的變量操作
#I=10
#((I++))
for循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))
do
循環體
done
控制變量初始化:僅在運行到循環代碼段時執行一次
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算
,而后再做條件判斷57
select 循環與菜單
select variable in list
do
循環體命令
done
select 循環主要用于創建菜單,按數字順序排列的
菜單項將顯示在標準錯誤上,并顯示 PS3 提示符,
等待用戶輸入
用戶輸入菜單列表中的某個數字,執行相應的命令
用戶輸入被保存在內置變量 REPLY 中。58
select 與 case
select 是個無限循環,因此要記住用 break 命令退
出循環,或用 exit 命令終止腳本。也可以按 ctrl+c
退出循環。
select 經常和 case 聯合使用
與 for 循環類似,可以省略 in list , 此時使用位置

參量

函數介紹
函數function是由若干條shell命令組成的語句塊,實現代碼
重用和模塊化編程。
它與shell程序形式上是相似的,不同的是它不是一個單獨的進程,不能獨立運行,而是shell程序的一部分。
函數和shell程序比較相似,區別在于:

  • Shell程序在子Shell中運行

  • 而Shell函數在當前Shell中運行。因此在當前Shell中,函數可以

對shell中變量進行修改
定義函數
函數由兩部分組成:函數名和函數體。
語法一:
function f_name {
…函數體…
}
語法二:
f_name() {
…函數體…
}
函數使用
函數的定義和使用:
可在交互式環境下定義函數
可將函數放在腳本文件中作為它的一部分
可放在只包含函數的單獨文件中
調用:函數只有被調用才會執行;
調用:給定函數名
函數名出現的地方,會被自動替換為函數代碼
函數的生命周期:被調用時創建,返回時終止62
函數返回值
函數有兩種返回值:
函數的執行結果返回值:
(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”

使用函數文件
可以將經常使用的函數存入函數文件,然后將函
數文件載入shell。
文件名可任意選取,但最好與相關任務有某種聯
系。例如: functions.main
一旦函數文件載入shell,就可以在命令行或腳本
中調用函數。可以使用set命令查看所有定義的函
數,其輸出列表包括已經載入shell的所有函數。
若要改動函數,首先用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, …調用這些參數;

還可以使用$@, $*, $#等特殊變量72

函數變量
變量作用域:
環境變量:當前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)!74
函數遞歸示例
示例: fact.sh
#!/bin/bash
#
fact() {
if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
fact 5
練習
1、寫一個服務腳本/root/bin/testsrv.sh,完成如下要求
(1) 腳本可接受參數: start, stop, restart, status
(2) 如果參數非此四者之一,提示使用格式后報錯退出
(3) 如是start:則創建/var/lock/subsys/SCRIPT_NAME, 并顯示“啟動成功”
考慮:如果事先已經啟動過一次,該如何處理?
(4) 如是stop:則刪除/var/lock/subsys/SCRIPT_NAME, 并顯示“停止完成”
考慮:如果事先已然停止過了,該如何處理?
(5) 如是restart,則先stop, 再start
考慮:如果本來沒有start,如何處理?
(6) 如是status, 則如果/var/lock/subsys/SCRIPT_NAME文件存在,則顯示
“ SCRIPT_NAME is running…”
如果/var/lock/subsys/SCRIPT_NAME文件不存在,則顯示“ SCRIPT_NAME
is stopped…”
其中: SCRIPT_NAME為當前腳本名
(7)在所有模式下禁止啟動該服務,可用chkconfig 和 service命令管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#!/bin/bash
#By: nextkare
#Time: 2016-08-202027
nowfile=`echo $0| sed 's#\./##'`
file=/var/lock/subsys/$nowfile
Start() {
[[ -e $file ]] && echo "Already started!" &amp;&amp; continue
touch $file && echo "starting… finished!"
}
Stop() {
[[ -e $file ]] && rm -f $file && echo "stopping… finished!"
[[ $? -ne 0 ]] && echo "No running service"
}
while true;do
read -p "please input you choice :" choice
case $choice in
start)
Start
;;
stop)
Stop
;;
restart)
Start
Stop
;;
status)
ls $file && /dev/null && echo "Service is running" || echo "Sevice stoped"
;;
*)
echo "Erorr!"
break
;;
esac
done

練習
2、編寫一個腳本/root/bin/copycmd.sh
(1) 提示用戶輸入一個可執行命令名稱;
(2) 獲取此命令所依賴到的所有庫文件列表
(3) 復制命令至某目標目錄(例如/mnt/sysroot)下的對應路徑下;
如: /bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd ==> /mnt/sysroot/usr/bin/passwd
(4) 復制此命令依賴到的所有庫文件至目標目錄下的對應路徑下:
如: /lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ldlinux-x86-64.so.2
(5)每次復制完成一個命令后,不要退出,而是提示用戶鍵入新的要復制的命
令,并重復完成上述功能;直到用戶輸入quit退出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

#!/bin/bash
#By: nextkara
#Time: 2016-08-211202
destinationdir=/mnt/sysroot
lib64=/usr/lib64
lib=/usr/lib
while true;do
read -p "please enter the command you want to copy: " commd
binfile=`which $commd | tail -1 | tr -d "\t"`
cp $binfile ${destinationdir}${binfile} && echo "copy program file(runable)…finished!"

filelist=` ldd $binfile | sed -r "s#.*=>##" | tr "\t" " " |cut -d" " -f2 | tr "\n" " "`
for x in $filelist;do
#normal file not soft link
cpfile=/usr`ls -lh  $x | grep  "^\-.*" | sed "s#.*[[:space:]]/#/#"`
[[ $cpfile == "/usr" ]] && continue
cp $cpfile ${destinationdir}${lib64}
#echo $cpfile
done
for y in $filelist;do
#link file
cpfile2=/usr`ls -lh  $y | grep  "^\l.*" | sed "s#.*[[:space:]]/#/#" | sed -r "s# ->.*##"`
[[ $cpfile2 != "/usr" ]] && cp -P $cpfile2 ${destinationdir}${lib64}
#echo $cpfile2

#copy the file that the link file refer to …
cpfile3=${lib64}/`ls -l $cpfile2 | sed -r "s#.*->; ##"`
#echo $cpfile3
cp $cpfile3 ${destinationdir}${lib64}
done
echo "copy files finished!"
done

練習
3、寫一個函數實現兩個數字做為參數,返回最大值

1
2
3
4
5
6
7
8
9
10
11
12

#!/bin/bash
#By: nextkara
#Time: 2016-08-211656
Num() {
  [[ $1 -gt $2 ]] && echo "$1 is more bigger" || echo "$2 is more bigger"
}
while true;do
read -p "please input the first number('q' for quit) ! :" num1
[[ $num1 == "q" ]] && exit
read -p "please input the second number ! :" num2
Num $num1 $num2
done

原創文章,作者:M20-石俊,如若轉載,請注明出處:http://www.www58058.com/38615

(0)
M20-石俊M20-石俊
上一篇 2016-08-21 20:42
下一篇 2016-08-21 20:45

相關推薦

  • MariaDB

    Mariadb 結構化數據–>關系型數據庫 范式:Entry(每一行來描述一個整體) 半結構化數據–>YAML,XML,JSON 非結構化數據–>日志文件 NoSQL 關系型數據庫:事務能力 ACID測試(原子性,一致性,隔離性,持久性) MariaDB or MySQL: 層次模型–>…

    Linux干貨 2016-11-15
  • 編譯安裝LAMP

    編譯安裝LAMP (1) 系統環境:CentOS 6, 7     CentOS 6:apr, apr-util的版本為1.3.9,不適用于httpd-2.4;     CentOS 7:apr, apr-util的版本為1.4+, (2) 開發環境…

    Linux干貨 2016-11-03
  • 文本處理工具sed

    處理文本的工具sed Stream EDitor,  行編輯器     sed 是一種流編輯器,它一次處理一行內容。處理時,把     當前處理的行存儲在臨時緩沖區中,稱為“模式空間”(     pa…

    Linux干貨 2016-08-10
  • 初識正則表達式

    正則表達式是個什么東東? 正則表達式,又稱正規表示法、常規表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE)。在很多文本編輯器里、命令中,通常要使用檢索、替換、放行和拒絕那些符合某個模式的文本。而正則表達式就是用于描述這些規則的工具。換句話說,正則表達式就是記錄文本規則的代碼。  摘自《正則表達式之…

    Linux干貨 2015-03-27
  • Linux如何快速查找需要執行的命令

    大家知道,對于熟悉命令行的用戶來說,命令行操作比圖形界面操作高效、簡潔,那么Linux是如何快速找到命令的位置呢?今天剛學了這一部分,與大家分享。         Linux將命令分為內部命令和外部命令,這是由于一些命令是常用的,需要常駐內存以減少檢索時間,所以集成在shell之…

    2017-07-15
  • 分布式存儲 Mogilefs 部署

    MogileFS是一個開源的分布式存儲的解決方案,主要工作組件由三部分組成:Tracker節點:生成映射表存儲于DB,并用于接收客戶端請求,通過查詢數據庫對客戶端提供后端所存儲的真實文件位置DB節點:主要存儲數據的元數據信息,可以理解為客戶端來獲取數據文件時提供的Key和真實存在存儲里面的文件名的對照表Storage節點:用于存儲文件的節點。工作流程,tra…

    2017-03-04

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-08-22 14:01

    文章對shell腳本各個語句的相關語法總結的很好,態度很端正,繼續保持哦。

欧美性久久久久