您好,登錄后才能下訂單哦!
承接第一部分進行總結分析
read
-p"prompt" //提示
-ttimeout
給變量默認值
varName=${varName:-value}
如果varName不空,則返回varName的值;否則varName會使用value作為其值
使用read參數[-p]后,允許在[-p]后面跟一字符串,在字符串后面跟n個shell變量。n個shell變量用來接收從shell界面輸入的字符串
[-p]用法:read –p “string” var1 var2…varn
練習:通過鍵盤給定一個文件的路徑,來判定文件內容類型
#!/bin/bash
read –p “Enter a file name:” fileName
type $fileName
通過鍵盤給定一個路徑,默認為/,來判定目錄下文件內容類型
例如:輸入用戶名,可返回其shell
#!/bin/bash
#
read-p "Plz input a username: " userName
ifid $userName &> /dev/null; then
echo "The shell of $userName is `grep"^$userName\>" /etc/passwd | cut -d: -f7`."
else
echo "No such user. stupid."
Fi
例子:顯示一個如下菜單給用戶:
cpu)show cpu infomation
mem)show memory infomation
*)quit
1、如果用戶選擇了cpu,則顯示/proc/cpuinfo文件的內容;
2、如果用戶選擇了mem,則顯示/proc/meminfo文件的內容;
3、退出
#!/bin/bash
#
echo"---------menu----------"
echo"cpu) show cpu infomation"
echo"mem) show memory infomation"
echo"*) quit"
echo"-------menu------------"
read-p "Plz give your choice: " choice
if[ "$choice" == 'cpu' ]; then
cat /proc/cpuinfo
elif[ "$choice" == 'mem' ]; then
cat /proc/meminfo
else
echo "Quit"
exit 3
fi
在第二個EOF前不要有換行、制表符或者空格
#!/bin/bash
#
cat<< EOF
-------menu------------
cpu)show cpu infomation
mem)show memory infomation
*)quit
-------menu------------
EOF
read-p "Plz give your choice: " choice
if[ "$choice" == 'cpu' ]; then
cat /proc/cpuinfo
elif[ "$choice" == 'mem' ]; then
cat /proc/meminfo
else
echo "Quit"
exit 3
fi
語法:
function F_NAME {
函數體
}
F_NAME() {
函數體
}
可調用:使用函數名
函數名出現的地方,會被自動替換為函數;
腳本:
函數的返回值:
函數的執行結果返回值:代碼的輸出
函數中的打印語句:echo, print
函數中調用的系統命令執行后返回的結果
執行狀態返回值:
函數體中最后一次執行的命令狀態結果
自定函數執行狀態的返回值:return #
函數可以接受參數:
在函數體中調用函數參數的方式同腳本中調用腳本參數的方式:位置參數
$1, $2, ...
$#, $*, $@
示例:服務腳本示例
#!/bin/bash
#
# chkconfig: 2345 67 34
#
srvName=$(basename $0)
lockFile=/var/lock/subsys/$srvName
start() {
if [ -f $lockFile];then
echo "$srvName is already running."
return 1
else
touch $lockFile
[ $? -eq 0 ] && echo "Starting $srvNameOK."
return 0
fi
}
stop() {
if [ -f $lockFile];then
rm -f $lockFile &> /dev/null
[ $? -eq 0 ] && echo "Stop $srvName OK"&& return 0
else
echo "$srvName is not started."
return 1
fi
}
status() {
if [ -f $lockFile ];then
echo "$srvName is running."
else
echo "$srvName is stopped."
fi
return 0
}
usage() {
echo "Usage:$srvName {start|stop|restart|status}"
return 0
}
case $1 in
start)
start
;;
stop)
stop ;;
restart)
stop
start ;;
status)
status ;;
*)
usage
exit 1 ;;
esac
練習:寫一個腳本,完成如下功能(使用函數):
1、提示用戶輸入一個可執行命令;
2、獲取這個命令所依賴的所有庫文件(使用ldd命令);
3、復制命令至/mnt/sysroot/對應的目錄中
解釋:假設,如果復制的是cat命令,其可執行程序的路徑是/bin/cat,那么就要將/bin/cat復制到/mnt/sysroot/bin/目錄中,如果復制的是useradd命令,而useradd的可執行文件路徑為/usr/sbin/useradd,那么就要將其復制到/mnt/sysroot/usr/sbin/目錄中;
4、復制各庫文件至/mnt/sysroot/對應的目錄中;
#!/bin/bash
#
target=/mnt/sysroot/
[ -d $target ] || mkdir $target
preCommand() {
if which $1 &> /dev/null; then
commandPath=`which--skip-alias $1`
return0
else
echo"No such command."
return1
fi
}
commandCopy() {
commandDir=`dirname $1`
[ -d ${target}${commandDir} ] || mkdir-p ${target}${commandDir}
[ -f ${target}${commandPath} ] || cp $1${target}${commandDir}
}
libCopy() {
for lib in `ldd $1 | egrep -o"/[^[:space:]]+"`; do
libDir=`dirname$lib`
[ -d${target}${libDir} ] || mkdir -p ${target}${libDir}
[ -f${target}${lib} ] || cp $lib ${target}${libDir}
done
}
read -p "Plz enter a command: "command
until [ "$command" == 'quit' ];do
if preCommand $command &>/dev/null; then
commandCopy $commandPath
libCopy $commandPath
fi
read -p "Plz enter a command: "command
done
信號種類
1) SIGHUP本信號在用戶終端連接(正常或非正常)結束時發出,通常是在終端的控制進程結束時,通知同一session內的各個作業,這時它們與控制端不再關聯。
2) SIGINT程序終止(interrupt)信號,在用戶鍵入INTR字符(通常是Ctrl-C)發出
3) SIGQUIT和SIGINT類似,但由QUIT字符(通常是Ctrl-/)來控制。進程在因收到SIGQUIT退出時會產生core文件,在這個意義1類似于一個程序錯誤信號。
4) SIGILL執行了非法指令,通常是因為可執行文件本身出現錯誤,或者試圖執行數據段。堆棧溢出時也有可能產生這個信號
trap命令用于在shell程序中捕捉到信號,之后可以有三種反應方式:
(1)執行一段程序來處理這一信號
(2)接受信號的默認操作
(3)忽視這一信號
trap對上面三種方式提供了三種基本形式:
第一種形式的trap命令在shell接收到signallist清單中數值相同的信號時,將執行雙引號中的命令串。
trap 'commands' signal-list
trap "commands" signal-list
第二種形式的trap命令恢復信號的默認操作:trap signal-list
第三種形式的trap命令允許忽視信號:trap " " signal-list
trap 'COMMAND' SIGINT(表示關閉進程)
例:寫一個腳本,能夠ping探測指定網絡內的所有主機是否在線,當沒有執行完時可接收ctrl+c命令退出。
#!/bin/bash
quitScript() {
echo "Quit..."
}
trap 'quitScript; exit 5' SIGINT
cnetPing() {
for i in {1..254}; do
if ping -c 1 -W 1 $1.$i &>/dev/null; then
echo "$1.$i is up."
else
echo "$1.$i is down."
fi
done
}
bnetPing() {
for j in {0..255}; do
cnetPing $1.$j
done
}
anetPing() {
for m in {0..255}; do
bnetPing $1.$m
done
}
netType=`echo $1 | cut -d"." -f1`
if [ $netType -ge 1 -a $netType -le 126 ];then
anetPing $netType
elif [ $netType -ge 128 -a $netType -le 191]; then
bnetPing $(echo $1 | cut -d'.' -f1,2)
elif [ $netType -ge 192 -a $netType -le 223]; then
cnetPing $(echo $1 | cut -d'.' -f1-3)
else
echo "Wrong"
exit 2
fi
數組:連續的多個獨立內存空間,每個內存空間相當于一個變量
數組元素:數組名+索引(從0開始編號)
索引的表示方式:
數字索引:a[index]
a[0], a[1]
bash 4.0的關聯數組
a[hello], a[hi]
聲明數組:declare -a ARRAR_NAME
關聯數組:declare -A ARRAY_NAME
支持稀疏格式:僅一維數組
數組的賦值:
(1)一次對一個元素賦值:
a[0]=$RANDOM
...
echo ${a[0]}
(2)一次對全部元素賦值:
a=(red blue yellowgreen)
一對括號表示是數組,數組元素用“空格”符號分隔開。
(3)按索引進行賦值:
a=([0]=green [3]=red[2]=blue [6]=yellow)
(4)命令替換:
logs=($(ls /var/log/*.log))
或者logs=(/var/log/*.log)
echo ${logs[0]}
(5)用戶輸入
read -a ARRAY
數組的訪問:
用索引訪問:ARRAY[index]
數組的長度:
${#ARRAY[*]}
${#ARRAY[@]}
eg:echo ${#test[*]}
echo ${#test[@]}
練習:寫一個腳本,生成10個隨機數,保存至數組中;而后顯示數組下標為偶數的元素;
#!/bin/bash
for i in {0..9};do
num[$i]=$RANDOM
if [ $[$i%2] -eq 0];then
echo "a[i] is${a[i]}"
fi
done
從數組中挑選某元素:
${ARRAY[@]:offset:number}
切片:
offset: 偏移的元素個數
number: 取出的元素的個數
${ARRAY[@]:offset}:取出偏移量后的所有元素
${ARRAY[@]}: 取出所有元素
數組復制:
要使用${ARRAY[@]}
$@: 每個參數是一個獨立的串
$*: 所有參數是一個串
向數組追加元素:非稀疏格式
mylogs,
mylogs[${#week[@]}]
示例:復制一個數組中下標為偶數的元素至一個新數組中
#!/bin/bash
declare -a mylogs
logs=(/var/log/*.log)
echo ${logs[@]}
for i in `seq 0 ${#logs[@]}`; do
if [ $[$i%2] -eq 0];then
index=${#mylogs[@]}
mylogs[$index]=${logs[$i]}
fi
done
echo ${mylogs[@]}
從數組中刪除元素:unset ARRAY[index]
練習1:生成10個隨機數,升序排序
#!/bin/bash
for((i=0;i<10;i++))
do
rnd[$i]=$RANDOM
done
echo -e "total=${#rnd[@]}\n${rnd[@]}\nBegin to sort"
for((i=9;i>=1;i--))
do
for((j=0;j<i;j++))
do
if [ ${rnd[$j]} -gt${rnd[$[$j+1]]} ] ;then
swapValue=${rnd[$j]}
rnd[$j]=${rnd[$[$j+1]]}
rnd[$[$j+1]]=$swapValue
fi
done
done
echo ${rnd[@]}
練習2:打印九九乘法表
#!/bin/bash
for((i=1;i<=9;i++))
do
strLine=""
for((j=1;i<=9;j++))
do
strLine=$strLine"$i*$j="$[$i*$j]"\t"
[ $i -eq $j ] && echo -e $strLine && break
done
done
字符串切片:
${string:offset:length}
取尾部的指定個數的字符:
${string: -length}
取子串:基于模式
${variable#*word}:在variable中存儲字串上,自左而右,查找第一次出現word,刪除字符開始至此word處的所有內容;
${variable##*word}:在variable中存儲字串上,自左而右,查找最后一次出現word,刪除字符開始至此word處的所有內容;
file='/var/log/messages'
${file#*/}: 返回的結果是var/log/messages
${file##*/}: 返回messages
${variable%word*}: 在variable中存儲字串上,自右而左,查找第一次出現word,刪除此word處至字串尾部的所有內容;
${variable%%world*}:在variable中存儲字串上,自右而左,查找最后一次出現word,刪除此word處至字串尾部的所有內容;
file='/var/log/messages'
${file%*/}: 返回的結果是/var/log
${file%%*/}: 返回結果為空
phonenumber='010-110-8'
${phonenumber%%-*}
${phonenumber##*-}
url="http://www.magedu.com:80"
取端口:${url##*:}
取協議:${url%%:*}
查找替換:
${variable/pattern/substi}: 替換第一次出現
${variable//pattern/substi}:替換所有的出現
${variable/#pattern/substi}:替換行首被pattern匹配到的內容
${variable/%pattern/substi}: 行尾
pattern可以使用globbing中的元字符:
*
?
查找刪除:
${variable/pattern}
${variable//pattern}
${variable/#pattern}
${variable/%pattern}
大小寫轉換:
小-->大:${variable^^}
大-->小:${variable,,}
只能對變量的單個字符做操作,eg:echo ${user^^a}
變量賦值操作:
${parameter:-word}
Use Default Values. If parameter is unset ornull, the expansion of word is substituted. Otherwise, the value of parameter is
substituted.
${parameter:=word}
Assign Default Values. If parameter is unset or null, the expansionof word is assigned to parameter. Thevalue of parameter is
then substituted. Positional parameters and special parametersmay not be assigned to in this way.
${parameter:?word}
Display Error if Null or Unset. If parameter is null or unset, the expansionof word (or a message to that effect if word is not
present) is written to the standarderror and the shell, if it is not interactive, exits. Otherwise, the value of parameter is
substituted.
${parameter:+word}
Use Alternate Value. If parameter is null or unset, nothing issubstituted, otherwise the expansion of word is substituted.
${variable:-string}
variable為空或未設定,那么返回string,否則,返回variable變量的值;
${variable:=string}
variable為空或未設定,則返回string,且將string賦值給變量variable,否則,返回variable的值;
為腳本使用配置文件,并確保某變量有可用值的方式
variable=${variable:-defaultvaule}
eg:
[ -f etc/sysconfig/test ] &&source /etc/sysconfig/test
myvar=${myvar:-www.mageedu.com}
echo $myvar
練習:讀取/etc/sysconfig/network文件,利用其HOSTNAME變量的值設置主機名;
9.4 bash編程之補充
mktemp命令:
mktemp [OPTIONS] filename.XXX
-d: 創建臨時目錄
--tmpdir=/path/to/somewhere :指定臨時文件所在的目錄
mktemp /tmp/tmp.XXX #XXX生成相同數量隨機字符
mktemp --tmpdir=/var/tmp tmp.XXX #指定目錄創建臨時文件
mktemp --tmpdir=/var/tmp -d tmp.XXX #指定目錄創建臨時目錄
install命令:
install [OPTIONS] SOURCE DEST
install [OPTIONS] SOURCE... DIR
install [OPTIONS] -d DIR ...
增強型的復制命令:
-o OWNER
-g GROUP
-m MODE
-d : 創建目錄
install /etc/fstab /tmp #復制文件到指定目錄
install --mode=644 /etc/fstab /tmp/ #復制時指定權限
install --owner=scholar /etc/fstab /tmp #復制時指定屬主
install --group=scholar /etc/fstab /tmp #復制時指定屬組
install -d /tmp/install #創建目錄
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。