shell入门

本文介绍了Vim编辑器的基础知识,包括三种模式的切换、常用命令和文本操作。接着讲解了Shell脚本的创建、执行,以及变量、字符串、数组、条件判断和循环等基础知识。此外,还涵盖了Shell脚本中的函数和并发处理概念。
摘要由CSDN通过智能技术生成

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 变量定义

规则:

  1. 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
  2. 等号两侧不能有空格
  3. 在bash中,变量默认类型都是字符串类型,无法进行数值运算。
  4. 变量的值如果有空格,需要使用双引号或单引号括起来。

变量名=变量值

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通过命令进行运算操作,不是直接运算

常见命令awkexprexpr

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 小于 10020 大于 15 : 返回 true
10 小于 10020 大于 100 : 返回 true
10 小于 520 大于 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 个字符串,然后每从管道内读出一个字符串就生成一个子进程,当管道

内没有字符串可读时就阻塞在那里,不能创建新的子进程,一直等到有新的字符串进来时才继续运行。

当每个并发进程执行完毕时又向管道内写入一个字符串,表示当前子进程已执行完毕,可以创建新的子

进程了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值