分享一个入门级可控多线程shell脚本方案
时间:2022-05-05
本文章向大家介绍分享一个入门级可控多线程shell脚本方案,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
说到 shell 可控多线程,网上分享的大部分是管道控制的方案。这种方案,张戈博客也曾经实战并分享过一次:《Shell+Curl 网站健康状态检查脚本,抓出中国博客联盟失联站点》,感兴趣的朋友可以看看。
下面张戈博客再分享另一种更容易理解的入门级可控多线程 shell 脚本方案:任务切割、各个击破。
先来 1 段场景描述:
某日,在鹅厂接到了这个任务,需要在 Linux 服务器中,对几千个 IP 进行一次 Ping 检测,只要取得 ping 可达的 IP 就好。如果单个 IP 去 ping 测试,虽然也可以完成任务,几千个 IP 还好了,如果更多呢?
鉴于这个 case 简单程度,第一时间先放弃了以前用过的管道方案,而是采用了各个击破的思想。
简单思路:
按照任务切割的“战略思想”,我先将这几千 IP 存入一个 iplist 文件,然后写一个分割函数,将这个文件分成多份临时 IP 清单,最后,用多线程遍历这些临时 IP 文件即可变相实现多线程了。
具体代码:
#!/bin/sh
#文本分割函数:将文本$1按份数$2进行分割
SplitFile()
{
linenum=`wc -l $1 |awk '{print $1}'`
if [[ $linenum -le $2 ]]
then
echo "The lines of this file is less then $2, Are you kidding me..."
exit
fi
Split=`expr $linenum / $2`
Num1=1
FileNum=1
test -d SplitFile || mkdir -p SplitFile
rm -rf SplitFile/*
while [ $Num1 -lt $linenum ]
do
Num2=`expr $Num1 + $Split`
sed -n "${Num1}, ${Num2}p " $1 > SplitFile/$1-$FileNum
Num1=`expr $Num2 + 1`
FileNum=`expr $FileNum + 1`
done
}
#Define some variables
SPLIT_NUM=${1:-10} #参数1表示分割成多少份即,开启多少个线程,默认10个
FILE=${2:-iplist} #参数2表示分割的对象,默认iplist文件
#分割文件
SplitFile $FILE $SPLIT_NUM
#循环遍历临时IP文件
for iplist in $(ls ./SplitFile/*)
do
#循环ping测试临时IP文件中的ip(丢后台)
cat $iplist | while read ip
do
ping -c 4 -w 4 $ip >/dev/null && echo $ip | tee -ai okip.log #ping 可达的IP则写入日志
done & #在while循环后面加上&符号,让这个嵌套循环在后台执行
done
将代码保存为 ping.sh 之后,执行 sh ping.sh iplist 100 的过程如下:
先将 iplist 切割成 100 份,存放在 SplitFile 文件夹中 然后,通过 for 循环读取这些分割文件,并在后台使用 while 循环对其中 ip 执行 ping 命令。
由于 while 是丢后台的, 所以 for 循环会一次性执行 100 个 while,相当于开启了 100 个线程,速度自然不可同日而语矣。
其中,切割的份数即你想要开启的多线程数量,很明显,这种任务分割的思路虽然没有管道方案来的高大上,但是其思想更加简单易懂,而且通用性也更好,适合入门级的简单多线程任务。
- sql基础知识:分页+排序
- Elasticsearch推荐插件篇(head,sense,marvel)
- sql基础知识:日期的常用用法
- 《Effective Java》—— 对于所有对象都通用的方法
- 《Effective Java》—— 创建与销毁对象
- web调试工具——Fiddler使用介绍(一)
- Windows c++应用程序通用日志组件(组件及测试程序下载)
- 快速排序
- 如何在Elasticsearch中安装中文分词器(IK+pinyin)
- Python抓取中文网页
- 《Effective Java》—— 读后总结
- unix共享内存要点
- LAMP=Linux+Apache+Mysql+Php
- unix共享内存要点
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Dynamic Programming - 120. Triangle
- Dynamic Programming - 63. Unique Paths II
- Tree - 109. Convert Sorted List to Binary Search Tree
- Tree - 108. Convert Sorted Array to Binary Search Tree Easy
- Tree - 236. Lowest Common Ancestor of a Binary Tree
- Tree - 235. Lowest Common Ancestor of a Binary Search Tree
- Tree - 98. Validate Binary Search Tree
- Tree - 199. Binary Tree Right Side View
- Tree - 103. Binary Tree Zigzag Level Order Traversal
- Tree - 107. Binary Tree Level Order Traversal II
- Trie - 212. Word Search II
- Trie - 211. Add and Search Word - Data structure design
- Trie - 208. Implement Trie (Prefix Tree)
- Tree - 337. House Robber III
- Tree - 250. Count Univalue Subtrees