本章概要:循環(huán)控制(for/while/until/select)、函數(shù)、數(shù)組、declare、eval、expect等。
#格式1 for 變量名 in 列表 ; do 循環(huán)體 done #格式2 for ((i=1;i<j;i++)) do 循環(huán)體 done
{1..100[..步進(jìn)]}、$(seq [start [stop]] end)
$@、$*
#當(dāng)CONDITION為真時(shí)。循環(huán) while CONDITION ; do 循環(huán)體 done #無限循環(huán) while : do statement done
while read line ; do
statement
done < /path/file
直到CONDITION為真時(shí)。退出循環(huán)
#直到CONDITION為真時(shí)。退出循環(huán)
until CONDITION ; do
循環(huán)體
done
select var in list
do
statement
done
N層循環(huán)是指循環(huán)嵌套的層
continue [N]:提前結(jié)束第N層的本輪循環(huán),而直接進(jìn)入下一輪判斷
break [N]:提前結(jié)束第N層循環(huán),最內(nèi)層為第1層
參量列表是指:腳本輸入的參數(shù)
shift [N]:用于將參量列表 list 左移指定次數(shù),缺省為左移一次
示例
[root.CentOS 7] ? cat break.sh while [ $# -gt 0 ] # or (( $# > 0 )) do echo $* shift done [root.CentOS 7] ? bash break.sh 1 2 3 45 6 7 8 9 0 1 2 3 45 6 7 8 9 0 2 3 45 6 7 8 9 0 3 45 6 7 8 9 0 45 6 7 8 9 0 6 7 8 9 0 7 8 9 0 8 9 0 9 0 0
#語法1(推薦) fname (){ 函數(shù)體 } #語法2 function fname{ 函數(shù)體 } #語法3 function fname() { 函數(shù)體 }
> cat function.main
#!/bin/bash
findit(){
echo hello
}
. function.main
或
source function.main
unset function_name
環(huán)境函數(shù)
使子進(jìn)程也可使用
聲明:export -f function_name
查看:export -f 或 declare -xf
函數(shù)參數(shù)
函數(shù)也可以使用$1,$2,$@,$*,$#
函數(shù)局部變量:local NAME=VALUE
函數(shù)遞歸
#!/bin/bash # fact() { if [ $1 -eq 0 -o $1 -eq 1 ]; then echo 1 else echo $[$1*$(fact $[$1-1])] fi } #函數(shù)調(diào)用 fact $1
信號(hào)可以用'kill -l'查看可用信號(hào)
#!/bin/bash trap 'echo “signal:SIGINT'' int trap -p for((i=0;i<=10;i++)) do sleep 1 echo $i done trap '' int trap -p for((i=11;i<=20;i++)) do sleep 1 echo $i done trap '-' int trap -p for((i=21;i<=30;i++)) do sleep 1 echo $i done
declare -a ARRAY_NAME
declare -A ARRAY_NAME 關(guān)聯(lián)數(shù)組
ARRAY_NAME[INDEX]=VALUE
ARRAY_NAME=('VAL1' 'VAL2' 'VAL3' ...)
ARRAY_NAME=([0]='VAL1' [3]='VAL2' ...)
read -a ARRAY
declare -a
${ARRAY_NAME[INDEX]}
${ARRAY_NAME[*]}
${ARRAY_NAME[@]}
${#ARRAY_NAME[*]}
${#ARRAY_NAME[@]}
unset ARRAY[INDEX]
unset ARRAY
${ARRAY[@]:offset:number}
ARRAY[${#ARRAY[*]}]=value
declare -A ARRAY_NAME
${#var}
: 返回字符串變量var的長度${var:offset}
: 返回字符串變量var中從第offset個(gè)字符后(不包括第offset個(gè)字符)的字符開始,到最后的部分,offset的取值在0 到 ${#var}-1 之間(bash4.2后,允許為負(fù)值)${var:offset:number}
:返回字符串變量var中從第offset個(gè)字符后(不包括第offset個(gè)字符)的字符開始,長度為number的部分${var: -length}
:取字符串的最右側(cè)幾個(gè)字符${var:offset:-length}
:從最左側(cè)跳過offset字符,一直向右取到距離最右側(cè)lengh個(gè)字符之前的內(nèi)容${var: -length:-offset}
:先從最右側(cè)向左取到length個(gè)字符開始,再向右取到距離最右側(cè)offset個(gè)字符之間的內(nèi)容${var#*word}
:其中word可以是指定的任意字符${var##*word}
:同上,貪婪模式,不同的是,刪除的是字符串開頭至最后一次由word指定的字符之間的所有內(nèi)容file=“var/log/messages”
${file#*/}: log/messages
${file##*/}: messages
${var%word*}
:其中word可以是指定的任意字符${var%%word*}
:同上,只不過刪除字符串最右側(cè)的字符向左至最后一次出現(xiàn)word字符之間的所有字符url=http://www.magedu.com:80
${url##*:} 80
${url%%:*} http
${var/pattern/substr}
:查找var,第一次被pattern所匹配,以substr替換之${var//pattern/substr}
: 查找var,所有能被pattern所匹配,以substr替換之${var/#pattern/substr}
:查找var,行首被pattern所匹配,以substr替換之${var/%pattern/substr}
:查找var,行尾被pattern所匹配,以substr替換之${var/pattern}
# 刪除var第一次被pattern匹配的${var//pattern}
# 刪除var所有被pattern匹配的${var/#pattern}
# 刪除var所有以pattern為行首匹配的${var/%pattern}
# 刪除var所有以pattern為行尾所匹配的${var^^}
:把var中的所有小寫字母轉(zhuǎn)換為大寫${var,,}
:把var中的所有大寫字母轉(zhuǎn)換為小寫變量配置方式 | str沒有配置 | str為空 | str已配置并非空 |
---|---|---|---|
var=${str-expr } | var=expr | var= | var=$str |
var=${str:-expr} | var=expr | var=expr | var=$str |
var=${str+expr} | var= | var=expr | var=expr |
var=${str:+expr} | var= | var= | var=expr |
var=${str=expr} | var=expr str=expr | str不變 var= | str不變 var=$str |
var=${str:=expr} | var=str=expr | var=str=expr | str不變 var=$str |
var=${str?expr} | expr輸出到stderr | var= | var=$str |
var=${str:?expr} | expr輸出到stderr | expr輸出到stderr | var=$str |
Shell變量一般是無類型的,但是bash Shell提供了declare和typeset兩個(gè)命令用于指定變量的類型,兩個(gè)命令是等價(jià)的
[OPTION] | 意義 |
---|---|
-r | 聲明或顯示只讀變量 |
-i | 將變量定義為整型數(shù) |
-a | 將變量定義為數(shù)組 |
-A | 將變量定義為關(guān)聯(lián)數(shù)組 |
-f | 顯示已定義的所有函數(shù)名及其內(nèi)容 |
-F | 僅顯示已定義的所有函數(shù)名 |
-x | 聲明或顯示環(huán)境變量和函數(shù) |
-l | 聲明變量為小寫字母 declare –l var=UPPER |
-u | 聲明變量為大寫字母 declare –u var=lower |
eval命令將會(huì)首先掃描命令行進(jìn)行所有的置換,然后再執(zhí)行該命令。該命令適用于那些一次掃描無法實(shí)現(xiàn)其功能的變量.該命令對變量進(jìn)行兩次掃描
+示例:
[root@server ~]# CMD=whoami [root@server ~]# echo $CMD whoami [root@server ~]# eval $CMD root [root@server ~]# n=10 [root@server ~]# echo {0..$n} {0..10} [root@server ~]# eval echo {0..$n} 0 1 2 3 4 5 6 7 8 9 10
eval var1=\$$var2
var1=${!var2}
[root@localhost ~]$var1=var2 [root@localhost ~]$var2=mage [root@localhost ~]$echo $var1 var2 [root@localhost ~]$echo \$$var1 $var2 [root@localhost ~]$eval echo \$$var1 mage [root@localhost ~]$echo ${!var1} mage
創(chuàng)建并顯示臨時(shí)文件,可避免沖突
mktemp [OPTION]... [TEMPLATE]
TEMPLATE: filenameXXX(X是隨機(jī)數(shù))
[OPTION] | 意義 |
---|---|
-d | 創(chuàng)建臨時(shí)目錄 |
-p DIR或–tmpdir=DIR | 指明臨時(shí)文件所存放目錄位置 |
mktemp /tmp/testXXX
tmpdir=`mktemp –d /tmp/testdirXXX`
mktemp --tmpdir=/testdir testXXXXXX
復(fù)制文件并設(shè)置屬性
install [OPTION]... SOURCE... DIRECTORY
[OPTION] | 意義 |
---|---|
-m MODE | 默認(rèn)755 |
-o OWNER | 所有者 |
-g GROUP | 所屬組 |
-d DIR | 創(chuàng)建空目錄 |
#復(fù)制文件file1,2,3到dir install -t dir file1 file2 file3 #復(fù)制文件srcfile到desfile并設(shè)置屬性 install -m 700 -o wang -g admins srcfile desfile #創(chuàng)建目錄/testdir/installdir并設(shè)置屬性 install –m 770 –d /testdir/installdir
expect 是由Don Libes基于Tcl( Tool Command Language )語言開發(fā)的,主要應(yīng)用于自動(dòng)化交互式操作的場景,借助 expect 處理交互的命令,可以將交互過程如:ssh登錄,ftp登錄等寫在一個(gè)腳本上,使之自動(dòng)化完成。尤其適用于需要對多臺(tái)服務(wù)器執(zhí)行相同操作的環(huán)境中,可以大大提高系統(tǒng)管理人員的工作效率
expect 語法:
expect [選項(xiàng)] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
選項(xiàng):
-c
:從命令行執(zhí)行expect腳本,默認(rèn)expect是交互地執(zhí)行的
示例:expect -c 'expect “\n” {send “pressed enter\n”}
-d
:可以輸出輸出調(diào)試信息
示例:expect -d ssh.exp
命令
expect中相關(guān)命令
spawn 啟動(dòng)新的進(jìn)程
send 用于向進(jìn)程發(fā)送字符串
expect 從進(jìn)程接收字符串
interact 允許用戶交互
exp_continue 匹配多個(gè)字符串在執(zhí)行動(dòng)作后加此命令
單一分支模式語法:
expect “hi” {send “You said hi\n'}
匹配到hi后,會(huì)輸出“you said hi”,并換行
expect 'hi' { send 'You said hi\n' } 'hehe' { send 'Hehe yourself\n' } 'bye' { send 'Good bye\n' } #匹配hi,hello,bye任意字符串時(shí),執(zhí)行相應(yīng)輸出。等同如下: expect { 'hi' { send 'You said hi\n'} 'hehe' { send 'Hehe yourself\n'} 'bye' { send ' Good bye\n'} }
#!/usr/bin/expect spawn scp /etc/fstab 192.168.8.100:/app expect { 'yes/no' { send 'yes\n';exp_continue } 'password' { send 'magedu\n' } } expect eof #!/usr/bin/expect spawn ssh 192.168.8.100 expect { 'yes/no' { send 'yes\n';exp_continue } 'password' { send 'magedu\n' } } interact #expect eof # 變量 #!/usr/bin/expect set ip 192.168.8.100 set user root set password magedu set timeout 10 spawn ssh $user@$ip expect { 'yes/no' { send 'yes\n';exp_continue } 'password' { send '$password\n' } } interact # 位置參數(shù) #!/usr/bin/expect set ip [lindex $argv 0] set user [lindex $argv 1] set password [lindex $argv 2] spawn ssh $user@$ip expect { 'yes/no' { send 'yes\n';exp_continue } 'password' { send '$password\n' } } interact #./ssh3.exp 192.168.8.100 root magedu # 執(zhí)行多個(gè)命令 #!/usr/bin/expect set ip [lindex $argv 0] set user [lindex $argv 1] set password [lindex $argv 2] set timeout 10 spawn ssh $user@$ip expect { 'yes/no' { send 'yes\n';exp_continue } 'password' { send '$password\n' } } expect ']#' { send 'useradd haha\n' } expect ']#' { send 'echo magedu |passwd --stdin haha\n' } send 'exit\n' expect eof #./ssh4.exp 192.168.8.100 root magedu # shell腳本調(diào)用expect #!/bin/bash ip=$1 user=$2 password=$3 expect <<EOF set timeout 20 spawn ssh $user@$ip expect { 'yes/no' { send 'yes\n';exp_continue } 'password' { send '$password\n' } } expect ']#' { send 'useradd hehe\n' } expect ']#' { send 'echo magedu |passwd --stdin hehe\n' } expect ']#' { send 'exit\n' } expect eof EOF #./ssh5.sh 192.168.8.100 root magedu
參考答案:(https://pan.baidu.com/s/1V1w5ChHGuU56akZk3MsPbQ)
用for實(shí)現(xiàn)
1 2 3 1 4 7
4 5 6 ===> 2 5 8
7 8 9 3 6 9
聯(lián)系客服