shell脚本进阶
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 [email protected]$ip
expect
"yes/no" send "yes\n";exp_continue
"password" send "$password\n"
interact
以上是关于shell脚本进阶的主要内容,如果未能解决你的问题,请参考以下文章