for 變量名 in 列表;do
循環體
done前端
列表生成方式有多重,詳情可查看其餘博客所總結。算法
雙小括號方法,即((…))格式,也能夠用於算術運算
雙小括號方法也可使bash Shell實現C語言風格的變量操做
I=10
((I++))shell
for循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))
do
循環體
done編程
while CONDITION; do
循環體
donecentos
進入條件:CONDITION爲true
退出條件:CONDITION爲false數組
until CONDITION; do
循環體
donebash
用於循環體中
continue [N]:提早結束第N層的本輪循環,而直接進入下一輪判斷;最內層爲第1層服務器
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
doneapp
用於循環體中
break [N]:提早結束第N層循環,最內層爲第1層
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
donessh
shift [n]
用於將參量列表 list 左移指定次數,缺省爲左移一次。
參量列表 list 一旦被移動,最左端的那個參數就從列表中刪除。 while 循環遍歷位置參量列表時,經常使用到 shift
例如:
./doit.sh a b c d e f g h
./shfit.sh a b c d e f g h
示例:doit.sh #!/bin/bash # Name: doit.sh # Purpose: shift through command line arguments # Usage: doit.sh [args] while [ $# -gt 0 ] # or while (( $# > 0 )) do echo $* shift done 示例:shift.sh #!/bin/bash #step through all the positional parameters until [ -z "$1" ] do echo "$1" shift done echo
while true; do
循環體
done
until false; do
循環體
Done
遍歷文件每一行這個寫法很實用,參考本身寫的建立用戶的腳本讀入每一行的命令就知道爲什麼實用了(由於它只把換行符當作分隔符,而不把空格當作分隔符,每一行當作一個長字符串存入變量中)
while read line; do
循環體
done < /PATH/FROM/SOMEFILE
PS3="Please input a number:"
select variable in list
do
循環體命令
done
PS3="please input a number:" select menu in backup clean config start stop status restart quit;do case $menu in *) echo $REPLY echo $menu;; esac done
函數由兩部分組成:函數名和函數體
help function
語法一:
f_name (){
...函數體...
}
語法二:
function f_name {
...函數體...
}
語法三:
function f_name () {
...函數體...
}
使子進程也可以使用
聲明:export -f function_name
查看:export -f 或 declare -xf
fork×××是一種惡意程序,它的內部是一個不斷在fork進程的無限循環,實質是一個簡單的遞歸程序。因爲程序是遞歸的,若是沒有任何限制,這會致使這個簡單的程序迅速耗盡系統裏面的全部資源
func_factorial(){ local input=$1 if func_ispositint $input ;then [ $input -gt 1 ] && echo $[`func_factorial $[input-1]`*input] || echo 1 else echo -e "Please input a positive integer" return 1 fi }
注意下面這兩個命令,它倆顯示是已經加載入內存中正在被引用的函數
action string true :它就會顯示正確結果 action string false : 它就會顯示錯誤結果
注意由於函數是在當前shell中運行,所以它的變量會影響當前腳本或者shell中的變量結果(也就是兩個變量名字相同會形成變量污染),所以 函數中的變量通常都定義爲 local variable=賦值;
三個返回:return 返回出函數;break,continue 返回出循環;exit 返回出shell(腳本) ;
函數相似腳本後面也能夠跟參數,用法如出一轍。注意$*和$@的區別,加上雙引號引用此參數傳遞到子函數或者子腳本中,前者表明一整個字符串做爲一個參數,後者表明分別做爲一個一個參數。不加上雙引號沒區別,這也是由於不加雙引號會把裏面的空格做爲分隔符。
#!/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 關聯數組:必須先聲明纔可使用,若是先使用了,必須unset以後再從新聲明纔可使用
注意:二者不可相互轉換
17:47[root@centos7 /etc/sysconfig/network-scripts]# abc=12334 17:54[root@centos7 /etc/sysconfig/network-scripts]# echo ${abc[0]} 12334 17:54[root@centos7 /etc/sysconfig/network-scripts]# echo ${abc} 12334 17:54[root@centos7 /etc/sysconfig/network-scripts]# echo ${#abc} 5 17:57[root@centos7 /data/scriptest]# array=([1]=12wad [5]=ff [6]=cvv [8]=1wd234) 17:57[root@centos7 /data/scriptest]# echo $array 17:57[root@centos7 /data/scriptest]# echo ${array[0]} 17:58[root@centos7 /data/scriptest]# echo ${array[1]} 12wad 17:58[root@centos7 /data/scriptest]# echo ${#array[1]} :第一個元素的長度 5 17:58[root@centos7 /data/scriptest]# echo ${#array[*]} :數組總長度,稀疏數組只看有幾個元素就是幾 4 17:58[root@centos7 /data/scriptest]# echo ${array[1]:2:3} :第一個元素內容切片 wad 17:58[root@centos7 /data/scriptest]# echo ${array[*]} 12wad ff cvv 1wd234 20:00[root@centos7 /data/scriptest]# echo ${array[*]:2:2} :取不一樣的數組元素,注意和元素內容切片的區分 ff cvv 20:00[root@centos7 /data/scriptest]# echo ${array[*]:2:3} ff cvv 1wd234
(1) 一次只賦值一個元素
ARRAY_NAME[INDEX]=VALUE
weekdays[0]="Sunday"
weekdays[4]="Thursday"
(2) 一次賦值所有元素(注意儘可能要加上引號,雖然空格也能夠做爲分隔符)
ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
(3) 只賦值特定元素
ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)
(4) 交互式數組值對賦值(注意有一個-a的選項)
read -a ARRAY
num=({1..10}) :1到10賦值給num[0]到num[9]
file=(*.sh) :當前目錄中sh後綴的文件名賦值給file數組
19:40[root@centos7 /data]# testarray[2]=12 19:40[root@centos7 /data]# testarray[5]=1234 19:40[root@centos7 /data]# echo ${testarray[2]} 12 19:40[root@centos7 /data]# declare -a declare -a testarray='( [2]="12" [5]="1234")' 19:40[root@centos7 /data]# testarray=( [1]=wade [3]=waef ) 19:40[root@centos7 /data]# echo ${testarray[2]} 19:40[root@centos7 /data]# declare -a declare -a testarray='([1]="wade" [3]="waef")' 上面會覆蓋,而後繼續,下面的不會覆蓋: 19:40[root@centos7 /data]# testarray[2]=12 19:44[root@centos7 /data]# testarray[5]=1234 19:44[root@centos7 /data]# declare -a declare -a testarray='([1]="wade" [2]="12" [3]="waef" [5]="1234")'
#!/bin/bash declare -i min max declare -a nums for ((i=0;i<10;i++));do nums[$i]=$RANDOM [ $i -eq 0 ] && min=${nums[$i]} && max=${nums[$i]}&& continue [ ${nums[$i]} -gt $max ] && max=${nums[$i]} [ ${nums[$i]} -lt $min ] && min=${nums[$i]} done echo 「All numbers are ${nums[*]}」 echo Max is $max echo Min is $min
#!/bin/bash # declare -a files files=(/var/log/*.log) declare -i lines=0 for i in $(seq 0 $[${#files[*]}-1]); do if [ $[$i%2] -eq 0 ];then let lines+=$(wc -l ${files[$i]} | cut -d' ' -f1) fi done echo "Lines: $lines."
${var##*word}:同上,貪婪模式,不一樣的是,刪除的是字符串開頭至最後一次由word指定的字符之間的全部內容
${var%word*}:其中word能夠是指定的任意字符
功能:自右而左,查找var變量所存儲的字符串中,第一次出現的word, 刪除字符串最後一個字符向左至第一次出現word字符串(含)之間的全部字符
${var^^}:把var中的全部小寫字母轉換爲大寫
${var,,}:把var中的全部大寫字母轉換爲小寫
-r 聲明或顯示只讀變量
-i 將變量定義爲整型數
-a 將變量定義爲數組
-A 將變量定義爲關聯數組
-f 顯示已定義的全部函數名及其內容
-F 僅顯示已定義的全部函數名
-x 聲明或顯示環境變量和函數 :或者export
-l 聲明變量爲小寫字母 declare –l var=UPPER :即便輸入大寫字母,也會變成小寫字母,下同相反
-u 聲明變量爲大寫字母 declare –u var=lower
eval命令將會首先掃描命令行進行全部的置換,而後再執行該命令。該命令適用於那些一次掃描沒法實現其功能的變量.該命令對變量進行兩次掃描
間接變量引用是指經過variable1得到變量值value的行爲
variable1=variable2
variable2=value
mktemp命令:建立並顯示臨時文件,可避免衝突
mktemp [OPTION]... [TEMPLATE]
TEMPLATE: filenameXXX
X至少要出現三個
install [OPTION]... [-T] SOURCE DEST 單文件
install [OPTION]... SOURCE... DIRECTORY
install [OPTION]... -t DIRECTORY SOURCE...
install [OPTION]... -d DIRECTORY...建立空目錄
expect 是由Don Libes基於Tcl( Tool Command Language )語言開發的,主要應用於自動化交互式操做的場景,藉助 expect 處理交互的命令,能夠將交互過程如:ssh登陸,ftp登陸等寫在一個腳本上,使之自動化完成。尤爲適用於須要對多臺服務器執行相同操做的環境中,能夠大大提升系統管理人員的工做效率
它執行的時候會捕獲屏幕上出現的關鍵字,而後根據出現的key來自動提交(輸入)內容
示例 #!/usr/bin/expect spawn scp /etc/fstab 192.168.8.100:/app expect { "yes/no" { send "yes\n";exp_continue } "password" { send "www.123\n" } } expect eof #!/usr/bin/expect spawn ssh 192.168.8.100 expect { "yes/no" { send "yes\n";exp_continue } "password" { send "www.123\n" } } interact #expect eof 示例:變量,變量設置和賦值用set,後面不加等號 #!/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 示例:位置參數:變量從0開始而不是shell中的從1開始 #!/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 www 示例:執行多個命令 #!/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 www |passwd --stdin haha\n" } send "exit\n" expect eof #./ssh4.exp 192.168.8.100 root www 示例:shell腳本調用expect,就是用多行重定向的方式來使用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 www |passwd --stdin hehe\n" } expect "]#" { send "exit\n" } expect eof EOF #./ssh5.sh 192.168.8.100 root www