微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

shell脚本进阶

for语句

for 变量名 in 取值列表; do 
    命令 
done

示例:

#!/bin/bash 
for i in {1..3}; do 
echo $i 
done 
#bash test.sh 
1 
2 
3

类似c语言风格,常用于计数,打印数字序列

#!/bin/bash 
for ((i=1;i<=5;i++)); do # 也可以i--   
echo $i 
done

while语句

while 条件表达式; do 
    命令 
done

实例:

#!/bin/bash 
N=0 
while [ $N -lt 5 ]; do
            let N++ 
            echo $N 
done 
#bash test.sh 
1 
2 
3 
4

当条件表达式为false时,终止循环
实例2:条件表达式为ture,将会产生死循环

#!/bin/bash 
while [ 1 -eq 1 ]; do 
    echo "yes" 
done

break和contime语句

break是终止循环
continue跳出当前循环
示例1:在死循环中,满足条件终止循环

#!/bin/bash 
N=0 
while true; do 
        let N++ 
        if [ $N -eq 5 ]; then 
            break 
        fi 
        echo $N 
    done 
    #bash test.sh 
    1 
    2 
    3 
    4

说明continue用法

#!/bin/bash 
N=0 
while [ $N -lt 5 ]; do 
    let N++ 
    if [ $N -eq 3 ]; then 
        continue 
    fi 
    echo $N done 
#bash test.sh 
1 
2 
4

case语句

case 模式名 in 
    模式1) 
        命令 
        ;; 
    模式2) 
        命令 
        ;; 
        *) 
        不符合以上模式执行的命令 
esac

示例:根据位置参数匹配不同的模式

#!/bin/bash 
case $1 in 
    start)
        echo "start."
        ;; 
    stop) 
        echo "stop."
        ;; 
    restart) 
        echo "restart." 
        ;; 
    *) 
    echo "Usage: $0 {start|stop|restart}" 
esac 
#bash test.sh 
Usage: test.sh {start|stop|restart} 
#bash test.sh start 
start. 
#bash test.sh stop 
stop. 
#bash test.sh restart 
restart.

select语句

select 变量 in 选项 1 选项2; do
    break
done

实例:

#!/bin/bash 
select MysqL_version in 5.1 5.6; do 
        echo $MysqL_version 
done
#bash test.sh 
1) 5.1 
2) 5.6 
#? 1 
5.1 
#? 2 
5.6

ps3="Select a number: " 可以定义select输入符

函数

格式: function关键字可写,也可不写

func() { 
    command 
}

实例:

#!/bin/bash 
func() { 
    echo "This is a function." 
} 
func  #调用
#bash test.sh 
This is a function.

实例2:函数返回值

#!/bin/bash 
func() { 
    VAR=$((1+1)) 
    return $VAR  #return在函数中定义状态返回值,返回并终止函数,但返回的只能是0-255的数字,类似于exit
    echo "This is a function." 
} 
func 
echo $? 
#bash test.sh
2

函数支持递归调用,就是自己调用自己
列如:

#!/bin/bash 
test() { 
    echo $1 
    sleep 1 
    test hello 
} 
test

会一直调用打印hello ,形成了闭环
fork×××及时函数递归调用

:(){ :|:& };: 或 .(){.|.&};.

:(){ } 定义一个函数函数名是冒号。
: 调用自身函数
| 管道符
: 再一次递归调用自身函数
:|: 表示每次调用函数":"的时候就会生成两份拷贝。
& 放到后台
; 分号是继续执行下一个命令,可以理解为换行。
: 最后一个冒号是调用函数
因此不断生成新进程,直到系统资源崩溃。

数组

变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组是相同类型的元素按一定顺序排列的集合。
顺序编号是数组的索引或者下标。
下标可以是任意的字符
自定义的下标为关联数组,必须先声明在使用,和普通数组之间不可以转换
下标不连续为稀疏数组
格式:

array=(元素1 元素2 元素3 ...)
用小括号初始化数组,元素之间用空格分隔。
定义方法1:初始化数组
array=(a b c)
定义方法2:新建数组并添加元素
array[下标]=元素
定义方法3:将命令输出作为数组元素
array=($(command))
交互式数组值对赋值
read -a array

数组操作:

获取所有元素: 
#echo ${array[*]} # *和@ 都是代表所有元素 
a b c 
获取元素下标: 
#echo ${!a[@]} 
0 1 2 
获取数组长度: 
#echo ${#array[*]} 
3 
获取一个元素: 
#echo ${array[0]} 
a 
获取第二个元素: 
#echo ${array[1]} 
b 
获取第三个元素: 
#echo ${array[2]} 
c 
添加元素: 
#array[3]=d 
#echo ${array[*]} 
a b c d 
添加多个元素: 
#array+=(e f g) 
#echo ${array[*]} 
a b c d e f g 
将数组的元素个数作为数组新元素的下标,新元素下标为原顺序编号个数
#array[${#array[@]}]=h
删除一个元素: 
#unset array[0] # 删除会保留元素下标 
#echo ${array[*]} 
b c d e f g 
删除数组: 
#unset array
关联数组:必须声明才能使用
#student[a]=aaa
#student[b]=bbb
#student[c]=ccc
#echo ${studen[a]}
ccc
#echo ${student[b]}
ccc
#echo ${student[c]}
ccc
#unset student  #删除标准数组
#declare -A studeny #声明
#student[a]=aaa
#student[b]=bbb
#student[c]=ccc
#echo ${studen[a]}
aaa
#echo ${student[b]}
bbb
#echo ${student[c]}
ccc

信号捕捉

信号(Signal):信号是在软件层次上对中断机制的一种模拟,通过给一个进程发送信号,执行相应的处理函数
进程可以通过三种方式来响应一个信号:
1)忽略信号,即对信号不做任何处理,其中有两个信号不能忽略:SIGKILL及SIGSTOP。
2)捕捉信号。
3)执行缺省操作,Linux对每种信号都规定了认操作

trap命令

trap命令定义shell脚本在运行时根据接收的信号做相应的处理。
命令格式:trap [-lp] [[arg] signal_spec ...]
-l # 打印编号1-64编号信号名称
arg # 捕获信号后执行的命令或者函数
signal_spec # 信号名或编号
一般捕捉信号后,做以下几个动作:
1)清除临时文件
2)忽略该信号
3)询问用户是否终止脚本执行
示例1:按CTRL+C不退出循环

#!/bin/bash 
trap "" 2 # 不指定arg就不做任何操作,后面也可以写多个信号,以空格分隔 
for i in {1..10}; do 
    echo $i 
    sleep 1 
done 
# bash a.sh 
1 
2 
3 
^C
4 
5 
6 
^C
7 
8
^C
9 
10

字符串切片:

${#var}:返回字符串变量var的长度
${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的
部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)
${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,
向后number个字符
${var: -length}:取字符串的最右侧几个字符
注意:冒号后必须有一空白字符
${var:offset:-length}:从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容
${var: -length:-offset}:先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之
间的内容

字符串处理:
基于模式取子串

${var#*word}:其中word可以是指定的任意字符
功能:自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字
符串(含)之间的所有字符
${var##*word}:同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所
有内容
${var%word*}:其中word可以是指定的任意字符
功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一
次出现word字符串(含)之间的所有字符
file="/var/log/messages"
${file%/*}: /var/log
${var%%word*}:同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符

Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令⽤于指定变量的类型,两个命令是等价的
declare [选项] 变量名

-r 声明或显示只读变量
-i 将变量定义为整型数
-a 将变量定义为数组
-A 将变量定义为关联数组
-f 显示已定义的所有函数名及其内容
-F 仅显示已定义的所有函数名
-x 声明或显示环境变量和函数
-l 声明变量为小写字母 declare –l var=UPPER
-u 声明变量为大写字母 declare –u var=lower

eval命令:
eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能
变量.该命令对变量进行两次扫描
间接变量引用
如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用

variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为
variable1=variable2
variable2=value

expect命令:
expect 语法:expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
选项

-c:从命令行执行expect脚本,认expect是交互地执行的
示例:expect -c 'expect "\n" {send "pressed enter\n"}
-d:可以输出输出调试信息
示例:expect -d ssh.exp
expect中相关命令
spawn 启动新的进程
send 用于向进程发送字符串
expect 从进程接收字符串
interact 允许用户交互
exp_continue 继续执行下面匹配

实例:非交互式登录远程主机

 #!/usr/bin/expect
 set ip 172.16.11.3
 set user root
 set password 123123
 set timeout 10
 spawn ssh $user@$ip
 expect {                                                         
 "yes/no" { send "yes\n";exp_continue }
 "password" { send "$password\n" }
 }
 interact

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐