1、vim编辑器基础
vim通过一些插件可以实现和IDE一样的功能
Vim是从 vi 发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。
简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是还是有可以进步的地方。
vim 则可以说是程序开发者的一项很好用的工具。尤其在Linux中,必须要会使用Vim(查看内容,编辑内容,保存内容)
所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在。
连 vim 的官方网站 (http://www.vim.org) 自己也说 vim 是一个程序开发工具而不是文字处理软件。
1.1 三种使用模式
基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode),输入模式(Insert mode)和底线命令模式(Last line mode)。这三种模式的作用分别是:
命令模式:
用户刚刚启动 vi/vim,便进入了命令模式。
此状态下敲击键盘动作会被Vim识别为命令,而非输入字符。比如我们此时按下i,并不会输入一个字符,i被当作了一个命令。
以下是常用的几个命令:
i 切换到输入模式,以输入字符。
x 删除当前光标所在处的字符。
: 切换到底线命令模式,以在最底一行输入命令。如果是编辑模式,需要先退出编辑模式! Esc键
若想要编辑文本:启动Vim,进入了命令模式,按下i,切换到输入模式。
命令模式只有一些最基本的命令,因此仍要依靠底线命令模式输入更多命令。
输入模式:
在命令模式下按下i就进入了输入模式。
在输入模式中,可以使用以下按键:
字符按键以及Shift组合,输入字符
ENTER,回车键,换行
BACK SPACE,退格键,删除光标前一个字符
DEL,删除键,删除光标后一个字符
方向键,在文本中移动光标
HOME/END,移动光标到行首/行尾
Page Up/Page Down,上/下翻页
Insert,切换光标为输入/替换模式,光标将变成竖线/下划线
ESC,退出输入模式,切换到命令模式
底线命令模式
在命令模式下按下:(英文冒号)就进入了底线命令模式。
底线命令模式可以输入单个或多个字符的命令,可用的命令非常多。
在底线命令模式中,基本的命令有(已经省略了冒号):
q 退出程序
w 保存文件
按ESC键可随时退出底线命令模式。
简单的说,我们可以将这三个模式想成底下的图标来表示:
1、vim 来建立一个名为test.txt 的文件,没有就创建,有就用vim/vi打开
vim test.txt
2、按下 i 进入输入模式(也称为编辑模式),开始编辑文字
在一般模式之中,只要按下 i, o, a 等字符就可以进入输入模式了!
在编辑模式当中,你可以发现在左下角状态栏中会出现 –INSERT- 的字样,那就是可以输入任意字符的提示。
这个时候,键盘上除了 Esc 这个按键之外,其他的按键都可以视作为一般的输入按钮了,所以你可以进行任何的编辑。
3、按下 ESC 按钮回到一般模式
好了,假设我已经按照上面的样式给他编辑完毕了,那么应该要如何退出呢?是的!没错!就是给他按下 Esc 这个按钮即可!马上你就会发现画面左下角的 – INSERT – 不见了!
4、在一般模式中按下 :wq 储存后离开 vim!
OK! 这样我们就成功创建了一个test.txt 的文件。
1.2命令模式快捷键
gg 光标移动到文本开始
G 光标移动文本尾
w 右移一个单词
nw 右移动几个单词
ggvG 全选
dd 删除光标所在行
0 光标行首
$ 光标行尾
dd 删除光标所在当前行
d0 删至行首
d$ 删至行尾
x或dl 删除光标当前字符
X 删除光标前一个字符
u 恢复上一步操作
ctrl r 重做上一步操作
shift u 恢复全部操作
yy:复制当前行
nyy:n表示大于1的数字,复制n行
yw:从光标处复制至一个单子/单词的末尾,包括空格
ye:从光标处复制至一个单子/单词的末尾,不包括空格
y$:从当前光标复制到行末
y0:从当前光标位置(不包括光标位置)复制之行首
y3l:从光标位置(包括光标位置)向右复制3个字符
y5G:将当前行(包括当前行)至第5行(不包括它)复制
y3B:从当前光标位置(不包括光标位置)反向复制3个单词
p 粘贴
/关键字符 查找
vim替换
语法为 :[addr]s/源字符串/目的字符串/[option]
全局替换命令为::%s/源字符串/目的字符串/g
[addr]: 表示检索范围,省略时表示当前行。
如:“1,20” :表示从第1行到20行;
“%” :表示整个文件,同“1,$”;
“. ,$” :从当前行到文件尾;
s :表示替换操作
[option] :表示操作类型
如:g 表示全局替换;
c 表示进行确认
p 表示替代结果逐行显示(Ctrl + L恢复屏幕);
省略option时仅对每行第一个匹配串进行替换;
如果在源字符串和目的字符串中出现特殊字符,需要用”\”转义
1. 基本的替换
:s/vivian/sky/ 替换当前行第一个 vivian 为 sky
:s/vivian/sky/g 替换当前行所有 vivian 为 sky
:n,$s/vivian/sky/ 替换第 n 行开始到最后一行中每一行的第一个 vivian 为 sky
:n,$s/vivian/sky/g 替换第 n 行开始到最后一行中每一行所有 vivian 为 sky
(n 为数字,若 n 为 .,表示从当前行开始到最后一行)
:%s/vivian/sky/(等同于 :g/vivian/s//sky/)替换每一行的第一个 vivian 为 sky
:%s/vivian/sky/g(等同于 :g/vivian/s//sky/g) 替换每一行中所有 vivian 为 sky
2. 可以使用 # 作为分隔符,此时中间出现的 / 不会作为分隔符
:s#vivian/#sky/# 替换当前行第一个 vivian/ 为 sky/
:%s+/oradata/apras/+/user01/apras1+ (使用+ 来替换 / ): /oradata/apras/替换成/user01/apras1/
2、shell概述
shell 是Linux内核的外壳,是操作系统底层与外层应用程序的接口,是一个命令解释器,接受应用程序/用户命令,然后调用操作系统内核。
2.1第一个shell脚本
1、创建脚本文件
touch helloworld.sh
2、vim编辑
vim helloworld.sh
3、文件内容
# !/bin/bash 指定命令解析器
echo "hellow world"
4、保存退出
5、执行shell脚本
脚本没有赋予执行权限
sh ./helloworld.sh
或者bash ./helloworld.sh
赋予执行权限、在执行
chmod +x ./helloworld.sh
./helloworld.sh
脚本的路径前加“.”或者source
source helloworld.sh
. helloworld.sh
shell注释:
单行#开始
多行
:<<x
注释内容...
注释内容...
注释内容...
x
x代替一类符号,x也可以是a b c !等等
查看shell文件
sh 参数 文件.sh
-n不要执行script,仅查询语法的问题
-v在执行script之前,先将script的内容输出到屏幕上
-x 将使用的脚本的内容输出到屏幕,该参数经常被使用
shell运行方式
工作目录执行:进入到shell文件当前目录 ./文件名.sh
绝对路径执行:
/home/tan/scripts/test.sh
或者
`pwd`/test.sh
sh执行
sh test.sh
bash test.sh
shell环境执行
.test.sh
source test.sh
3、shell变量
3.1 变量定义
规则:
- 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
- 等号两侧不能有空格
- 在bash中,变量默认类型都是字符串类型,无法进行数值运算。
- 变量的值如果有空格,需要使用双引号或单引号括起来。
变量名=变量值
number=18 #定义变量
usset number #撤销变量
echo $number #引用变量
或者echo ${number} #引用变量
str="helloworld" #定义只读变量
readonly str
3.2 变量类型
**局部变量:**当前shell有效,其它shell无效
**环境变量:**所有程序都能访问的变量
**shell变量:**shell程序设置的特殊变量,含有局部变量和环境变量
3.3 shell字符串变量
单引号
str='hello world'
特点:原样输出
双引号
str="hello world"
特点:可以进行转义字符转义
获取字符串长度
str="study"
l=${#str}
截取子字符串
str=www.baidu.com
echo ${str:0:4}#下标为0截取4个
从前往后最短匹配
str=www.baidu.com
echo ${str#*.}
baidu.com
从前往后最长匹配
str=www.baidu.com
echo ${str##*.}
com
从后往前最短
str=www.baidu.com
echo ${str%.*}
www.baidu
从后往前最长
str=www.baidu.com
echo ${str%%.*}
www
替换
替换匹配第一个
str=www.baidu.com
echo ${str/baidu/sihu}
www.sihu.com
匹配替换所有
str=www.baidu.com
echo ${str//w/W}
WWW.baidu.com
i=1
j=1
a=i++ 先赋值a,i在+1
a=1
i=2
b=++j 先j+1,在赋值b
j=2
b=2
4、shell数组
4.1 定义数组
age=(12 13 14)
或者单个赋值
age[0]=12
age[1]=13
age[2]=14
4.2读取数组元素
echo ${age[0]} #下标为0的元素
echo ${age[*]} #输出数组中全部元素
或者
echo ${age[@]}
4.3数组长度
length=${#age[@]}
或者
length=${#age[*]}
length=${age[0]} #下标为0的元素的长度
4.4数组删除
unset age[0]
unset age
echo ${age[*]}
4.5数组截取
echo ${age[*]:1:2} #下标1开始,截取2个字符
4.6数组替换
echo ${age[*]/2/3}
4.7数组删除
匹配o
从左往右最短
echo ${age[@]#o*}
从左往右最长
echo ${age[@]##o*}
从右往左最短
echo ${age[@]%o*}
从右边往左最长
echo ${age[@]%%o*}
4.8遍历数组
for in
a=(wo shi wang yi hui )
for n in ${a[@]}
do
echo $n
done
for
a=(wo shi wang yi hui )
for((i=0;i<${#a[@]};i++))
do
echo ${a[i]}
done
while
a=(wo shi wang yi hui )
i=0
while [ $i -lt ${#a[@]} ]
do
echo ${a[i]}
let i++
done
4.9关联数组
关联数组使用字符串作为下标,而不是整数。关联数组也称“**键值对(key-value)”**数组,key为下标,value为元素值。
(1)关联数组的声明
方式: declare -A 数组名
(2)关联数组赋值
一次赋一个值
数组名[索引]=值
一次赋多个值
数组名=([索引1]=值1 [索引2]=值2 [索引3]=值3)
declare -A arry1 #声明关联数组arry1
arry1=([name]="zhangsan" [sex]=nan [age]=17)
arry1[addr]="China"
arry1[email]="xxx@mail.com"
echo "name对应的值为:${arry1[name]}"
echo "email对应的值为:${arry1[email]}"
echo "该关联数组一共有:${#arry1[*]}个元素"
echo "数组全部元素为:${arry1[*]}"
echo "数组的所有下标为:${!arry1[*]}"
5、shell 传递参数
参数处理的特殊变量
$# | 传递到脚本的参数个数 |
---|---|
$* | 以一个单字符串显示所有向脚本传递的参数。 如"$*“用「”」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与 ∗ 相同,但是使用时加引号,并在引号中返回每个参数。如 " *相同,但是使用时加引号,并在引号中返回每个参数。 如" ∗相同,但是使用时加引号,并在引号中返回每个参数。如"@“用「”」括起来的情况、以"$1" “ 2 " … " 2" … " 2"…"n” 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
./test.sh 1 2 3 #执行shell文件传递了参数 1 2 3
value1=$1 #获取第一个参数
value2=$2 #获取第二个参数
value3=$3 #获取第三个参数
value4=$# #获取参数个数
string=$* #传递参数用字符串拼接起来
6、shell基本运算符
支持类型:
- 算数运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试运算符
**注意:**shell通过命令进行运算操作,不是直接运算
常见命令awk 和 expr,expr
6.1算术运算符
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ a== b] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
结果
a + b : 30
a - b : -10
a * b : 200
b / a : 2
b % a : 0
a 不等于 b
6.2关系运算符
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
实例
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
结果
10 -eq 20: a 不等于 b
10 -ne 20: a 不等于 b
10 -gt 20: a 不大于 b
10 -lt 20: a 小于 b
10 -ge 20: a 小于 b
10 -le 20: a 小于或等于 b
6.3布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
实例
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi
结果
10 != 20 : a 不等于 b
10 小于 100 且 20 大于 15 : 返回 true
10 小于 100 或 20 大于 100 : 返回 true
10 小于 5 或 20 大于 100 : 返回 false
6.4逻辑运算符
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 |
实例
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
结果
返回 false
返回 true
6.5字符串运算符
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否不相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n “$a” ] 返回 true。 |
$ | 检测字符串是否不为空,不为空返回 true。 | [ $a ] 返回 true。 |
实例
a="abc"
b="efg"
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
结果
abc = efg: a 不等于 b
abc != efg : a 不等于 b
-z abc : 字符串长度不为 0
-n abc : 字符串长度不为 0
abc : 字符串不为空
6.6文件测试运算符
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
---|---|---|
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
实例
file="/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
结果
文件可读
文件可写
文件可执行
文件为普通文件
文件不是个目录
文件不为空
文件存在
7、流程控制
[]关系运算符 (())里面是算术运算符
7.1 if判断
单分支
if [条件判断]; then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
多分支
if [ 条件判断 ]
then
echo "未成年人"
elif [ 条件判断 ]
then
echo "中年人"
else
echo "成年人"
fi
7.2 case … esac
case … esac 为多选择语句,与其他语言中的 switch … case 语句类似,是一种多分支选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case … esac 语句,esac(就是 case 反过来)作为结束标记。
可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
case 变量名 in
满足条件1)
程序
;;
满足条件2)
程序
;;
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
test命令
数值测试
#!/bin/bash
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
字符串测试
test –n 字符串 #字符串的长度非零
test –z 字符串 #字符串的长度是否为零
test 字符串1=字符串2 #字符串是否相等,若相等返回true
test 字符串1!=字符串2 #字符串是否不等,若不等反悔false
#!/bin/bash
num1="xiaogongjiang"
num2="xiaogongjiang"
if test num1=num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
判断文件
test File1 –ef File2 #两个文件是否为同一个文件,可用于硬连接。主要判断两个文件是否指向同一个inode。
test File1 –nt File2 #判断文件1是否比文件2新
test File1 –ot File2 #判断文件1比是否文件2旧
test –b file #文件是否块设备文件
test –c File #文件并且是字符设备文件
test –d File #文件并且是目录
test –e File #文件是否存在 (常用)
test –f File #文件是否为正规文件 (常用)
test –g File #文件是否是设置了组id
test –G File #文件属于的有效组ID
test –h File #文件是否是一个符号链接(同-L)
test –k File #文件是否设置了Sticky bit位
test –b File #文件存在并且是块设备文件
test –L File #文件是否是一个符号链接(同-h)
test –o File #文件的属于有效用户ID
test –p File #文件是一个命名管道
test –r File #文件是否可读
test –s File #文件是否是非空白文件
test –t FD #文件描述符是在一个终端打开的
test –u File #文件存在并且设置了它的set-user-id位
test –w File #文件是否存在并可写
test –x File #文件属否存在并可执行
#!/bin/bash
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
判断表达式
if test 表达式 #表达式为真
if test !表达式 #表达式为假
test 表达式1 –a 表达式2 #两个表达式都为真
test 表达式1 –o 表达式2 #两个表达式有一个为真
test 表达式1 ! 表达式2 #条件求反
7.3 for循环
for ((初始值; 循环控制条件; 变量变化 ))
do
程序
done;
7.4 wile循环
while [ 条件判断式 ]
do
程序
done;
7.5until循环
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
until [ 条件判断式 ]
do
程序
done;
8、shell函数
关键字 函数名(){
程序;
return 返回值
}
printHelloworld(){ #简单函数
echo "hello world"
}
printHelloworld(){ #参数函数
echo "$1"
echo "$2"
echo "$3"
}
printHelloworld "study" "day day" "up" #调用函数传入参数
shell 函数关键字function,使用后函数名后可以不需要()
function printHelloworld{ #function关键字定义函数
echo "hello world"
}
9、Shell并发
shell并发利用$、wait、管道文件
初始
#!/bin/bash
for(( i = 0; i < ${count}; i++ ))
do
commands1
done
commands2
上面的脚本,因为每个commands1都挺耗时的,所以打算使用并发编程,这样就可以节省大量时
间了。
改进1
#!/bin/bash
for(( i = 0; i < ${count}; i++ ))
do
{
commands1
}&
done
commands2
这样的话 commands1 就可以并行执行了。 实质是将 commands1 作为后台进程在执行,这样主
进程就不用等待前面的命令执行完毕之后才开始执行接下来的命令。
但是本来目的是让 commands1 的这个循环都执行结束后,再用 command2 去处理前面的结
果。如果像上面这样写的话,在 commands1 都还没结束时就已经开始执行commands2 了,得
到了错误的结果
改进2
#!/bin/bash
for(( i = 0; i < ${count}; i++ ))
do
{
commands1
}&
done
wait
commands2
最终通过进程控制数量
#!bin/bash
PRONUM=10 # 进程个数
tmpfile="$$.fifo" # 临时生成管道文件
mkfifo $tmpfile
exec 6<>$tmpfile
rm $tmpfile
for(( i=0; i<$PRONUM; i++ ))
do
echo "init."
done >&6
for(( i = 0; i < ${count}; i++ ))
do
read line
#echo $line
{
commands
echo "line${i} finished."
} >&6 &
done <&6
wait
初始时给管道内写入 PRONUM 个字符串,然后每从管道内读出一个字符串就生成一个子进程,当管道
内没有字符串可读时就阻塞在那里,不能创建新的子进程,一直等到有新的字符串进来时才继续运行。
当每个并发进程执行完毕时又向管道内写入一个字符串,表示当前子进程已执行完毕,可以创建新的子
进程了。