朝花夕拾-4-shell

引言

shell,我们常常会用到,以其强大的功能,会帮助我们解决非常多棘手的问题。近期遇到一个问题,要跑非常多case,假设串行的执行,须要非常久。能不能让他们并行起来,但又不能全部case都并行执行呢?,由于全部case同一时候执行,机器会挂掉的。

1,方式1

比較直接的一种方式是,维护两个文件队列(*.start和*.stop)分别记录全部case的执行状态,然后依据并发数量来获取和分配资源。

代码例如以下:

multi.sh:

#!/bin/bash

#Rill create to run cases parallel
#2014-05-22 

#mkdir ./case_status
#declare -i pc_num
readonly pc_num = 3
case_list = "a b c d e f"

function get_start_num()
{
	num = 0
	for var in $case_list
	do
		if [ -e $var.start -a -f $var.start]; then
			num = num + 1
		fi
	done

	return $num
}

function get_case_stop()
{
	case $1 in
	"a")
		echo "get case: $1 not stop"
		rerurn 0
	;;

	"b")
		echo "get case: $1 stop"
		return 1
	;;

	"c")
		echo "get case: $1 not stop"
		rerurn 0
	;;

	"d")
		echo "get case: $1 stop"
		rerurn 1
	;;

	"e")
		echo "get case: $1 stop"
		rerurn 1
	;;

	"f")
		echo "get case: $1 stop"
		rerurn 1
	;;

	*)
		echo "case $1 not exist"
		exit 1;
	;;
}

for each_d in ${case_list};
do
	if [ get_start_num -lt $pc_num ];then
		if [ ! -e $each_d.start ]; then
			if [ ! -e $each_d.stop ]; then
				touch $each_d.start
				#start one new case
			else
				echo "$each_d already stoped"
				rm $each_d.start
			fi

		else
			if [ ! -e $each_d.stop ]; then
				echo "$each_d running......"
				if[ get_case_stop $each_d eq 1];then
					touch $each_d.stop
					rm $each_d.start
				fi
			else
				echo "$each_d error!"
			fi

		fi
	fi
done

须要注意的是採用这样的方式的话,须要获得每一个case的结束状态,这个能够通过case执行结束时的输出log中分析得到。

尽管有awk等强大的工具,可是,分析获得不同case的结束信息仍然是一项艰巨的任务。

有没有其它的方式呢?

有。

2,方式2

细致分析全部的cases開始,结束的情景,发现和fifo文件的特性非常相似,于是就想到用fifo来实现并发控制。

例如以下:

multi.sh:

#!/bin/bash

#Rill create to run cases parallel
#2014-05-22 

case_list="a b c d e f g h i j k l m n o"

readonly parallel_num=3
readonly fifo_id=9
readonly fifo_name=fd2
readonly log_name=log.log

#create log file
if [ -e ${log_name} -a -f ${log_name} ];then
	rm -f ${log_name}
fi
touch ${log_name}
echo "all cases begin time:$(date +%Y-%m-%d-%H:%M:%S)" >>${log_name}

#create fifo file
if [ -e ${fifo_name} -a -f ${fifo_name} ];then
	rm -f ${fifo_name}
fi
mkfifo ${fifo_name}

#bind fifo to fifo_id
eval "exec ${fifo_id}<>${fifo_name}"

#init fifo
for (( idx=0;idx<${parallel_num};idx=idx+1 ))
do
echo -n -e "1\n" >>${fifo_name}
done

#multi main body
for each_case in ${case_list};
do
	read -u ${fifo_id}
	{
		echo "${each_case} start:$(date +%Y-%m-%d-%H:%M:%S)" >>${log_name}
		sleep 1  #case running
		echo "${each_case} stoped:$(date +%Y-%m-%d-%H:%M:%S)" >>${log_name}
		echo -ne "1\n" >>${fifo_name}
	} &
done

#wait all the cases stoped
wait

echo "all cases finish time:$(date +%Y-%m-%d-%H:%M:%S)" >>${log_name}

#remove the fifo
rm -f ${fifo_name}

从中能够发现,我们不须要再为获得case的结束状态而烦恼了。

以下是执行结果,一共15个case,每一个case执行1秒,并发数量设置为3,全部case执行完须要6.4秒左右。

3,shell參数传递

平时我们在使用shell脚本时,往往要向脚本中指定參数,这些參数能够直接写在命令行的后面,可是这样做对參数顺序要求非常强,使用起来比較困难。

这时我们能够通过在參数前面添加标示来实现。

#!/bin/bash

#
# shell test
# Rill
# 2014-09-28

opr1=x
opr2=x
opr3=x

while [ -n "$(echo $1 | grep ‘-‘)" ];do
    case $1 in
	-h | --help)
	    echo "./test.sh -opr1 a -opr2 b -opr3 c"
	    exit 0
	    ;;
	-opr1)
	    opr1=$2
	    shift
	    ;;

	-opr2)
	    opr2=$2
	    shift
	    ;;

	-opr3)
	    opr3=$2
	    shift
	    ;;

    esac

    shift

done

echo "opr1=${opr1}  opr2=${opr2}  opr3=${opr3}"

验证结果:

4,小结

shell非常久都不用了,本小结就当“朝花夕拾”吧。

时间: 2024-10-10 11:55:45

朝花夕拾-4-shell的相关文章

【Linux系列】【基础版】第四章 Shell基础之正则表达式

4. Shell基础之正则表达式     4.1 正则就是一串有规律的字符串         4.1 grep              4.1.1 格式: grep [-cinrvABC] 'word' filename             4.1.2 -c //count,表示行数             4.1.3 -i //不区分大小写             4.1.4 -n  //显示行号             4.1.5 -r  //遍历所有子目录             4

linux Shell函数

Shell函数类似于Shell脚本,里面存放了一系列的指令,不过Shell的函数存在于内存,而不是硬盘文件,所以速度很快,另外,Shell还能对函数进行预处理,所以函数的启动比脚本更快. 1.函数定义 1 2 3 4 function 函数名() {     语句     [return] } 关键字function表示定义一个函数,可以省略,其后是函数名,有时函数名后可以跟一个括号,符号"{"表示函数执行命令的入口,该符号也可以在函数名那一行,"}"表示函数体的结

Shell实现跳板机,为什么用跳板机

整理自:http://blog.chinaunix.net/uid-22101889-id-3167454.html 注意:请谨慎使用,到现在为止,使用了,我还没找到改回去的方法. 1.     问题 第一.很多大公司的服务器都不允许直接登录,而是通过一个跳板机才能登录过去.在跳板机中,通常只能执行几个少数命令(如SSH),而其他命令是不允许执行的,那么怎样才能实现这个功能呢? 第二.一些小公司,由于服务器比较少,不需要什么跳板机之类的说法,公司的开发运维人员加起来也就那么十几二十人,通常大家都

linux shell基础语法

1.第一个Shell脚本 打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用php写shell 脚本,扩展名就用php好了. 输入一些代码: #!/bin/bash echo "Hello World !" "#!" 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell.echo命令用于向窗口输出文本. 运行Shell脚本有两种方法. 1.1作为可执行程序 将上面的代码保存为t

shell中test命令方法详解

test命令用法.功能:检查文件和比较值 1)判断表达式 if test  (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2                  两个表达式都为真 test 表达式1 –o 表达式2                 两个表达式有一个为真 2)判断字符串 test –n 字符串                                   字符串的长度非零 test –z 字符串                          

shell脚本

-e filename 如果 filename存在,则为真 [ -e /var/log/syslog ]-d filename 如果 filename为目录,则为真 [ -d /tmp/mydir ]-r filename 如果 filename可读,则为真 [ -r /var/log/syslog ]-w filename 如果 filename可写,则为真 [ -w /var/mytmp.txt ]-x filename 如果 filename可执行,则为真 [ -L /usr/bin/gr

20.5 Shell脚本中的逻辑判断;20.6 文件目录属性判断;20.7 if特殊用法;20.8 20.9 cace判断(上下)

扩展: select用法 http://www.apelearn.com/bbs/thread-7950-1-1.html 20.5 Shell脚本中的逻辑判断 格式1:if 条件 ; then 语句; fi 1. 创建if1.sh测试脚本: [[email protected] ~]# vi if1.sh a=5,如果a大于3,满足这个条件,显示ok 添加内容: #!/bin/bash a=5 if [ $a -gt 3 ] then echo ok fi 2. 执行if1.sh脚本: [[e

20.1 Shell脚本介绍;20.2 Shell脚本结构和执行;20.3 date命令用法;20.4 Shell脚本中的变量

20.1 Shell脚本介绍 1. shell是一种脚本语言 aming_linux blog.lishiming.net 2. 可以使用逻辑判断.循环等语法 3. 可以自定义函数 4. shell是系统命令的集合 5. shell脚本可以实现自动化运维,能大大增加我们的运维效率 20.2 Shell脚本结构和执行 1. 开头(首行)需要加: #!/bin/bash 2. 以#开头的行作为解释说明: 3. 脚本的名字以.sh结尾,用于区分这是一个shell脚本 4. 执行.sh脚本方法有两种:

shell 中seq的用法 echo -n用法

用法:seq [选项]... 尾数 或:seq [选项]... 首数 尾数 或:seq [选项]... 首数 增量 尾数 从1循环到100的两种方法(bash 其它的shell没试过)for x in `seq 1 100`;do echo $x;donefor x in {1..100};do echo $x;done echo -n 不换行输出 $echo -n "123" $echo "456" 最终输出 123456 echo -e 处理特殊字符 若字符串中