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