shell多个脚本怎么shell 并发脚本执行

shell多个脚本怎么并发执行 - 开源中国社区
当前访客身份:游客 [
当前位置:
例如我的shell里面有:
应该怎么并行运行这三个sh?
共有9个答案
<span class="a_vote_num" id="a_vote_num_
#!bin/bash
tmpfile="$$.fifo"
#临时生成管道文件
mkfifo $tmpfile
exec 6&&$tmpfile
rm $tmpfile
for(( i=0; i&$PRONUM; i++ ))
&&&&&&& echo "init."
for(( i = 0; i & ${count}; i++ ))
&&&&&&& read line
&&&&&&& #echo $line
&&&&&&&&&&&&&&& commands
&&&&&&&&&&&&&&& echo "line${i} finished."
&&&&&&& } &&6 &
<span class="a_vote_num" id="a_vote_num_
<span class="a_vote_num" id="a_vote_num_
linux的定时任务,crontab
--- 共有 2 条评论 ---
: cron里面时间一样就行了,系统会给你安排的~
(2年前)&nbsp&
定时任务还是一个一个的执行的,先a.sh,再b.sh最后c.sh,我现在想要这三个同时执行
(2年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
丢到后台执行不就OK了
--- 共有 1 条评论 ---
(2年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
执行耗时极短的,很难做到同时执行,或者编程多进程多线程同步执行。耗时长的直接丢后台或者计划任务。
<span class="a_vote_num" id="a_vote_num_
#!/bin/bash
a=`date +%s.%N`
echo $a & /tmp/a.log
#!/bin/bash
b=`date +%s.%N`
echo $b & /tmp/b.log
#!/bin/bash
c=`date +%s.%N`
echo $c & /tmp/c.log
第一次用crontab执行结果如下:
a.log b.log c.log分别如下:
第二次执行结果如下:
可见crontab不是同步的,但是执行顺序并非你说的如此 应该是随机的
<span class="a_vote_num" id="a_vote_num_
引用来自“lgscofield”的评论#!bin/bash
tmpfile="$$.fifo"
#临时生成管道文件
mkfifo $tmpfile
exec 6&&$tmpfile
rm $tmpfile
for(( i=0; i&$PRONUM; i++ ))
&&&&&&& echo "init."
for(( i = 0; i & ${count}; i++ ))
&&&&&&& read line
&&&&&&& #echo $line
&&&&&&&&&&&&&&& commands
&&&&&&&&&&&&&&& echo "line${i} finished."
&&&&&&& } &&6 &
这个测试出来也是不同步的!!
<span class="a_vote_num" id="a_vote_num_
引用来自“lgscofield”的评论#!bin/bash
tmpfile="$$.fifo"
#临时生成管道文件
mkfifo $tmpfile
exec 6&&$tmpfile
rm $tmpfile
for(( i=0; i&$PRONUM; i++ ))
&&&&&&& echo "init."
for(( i = 0; i & ${count}; i++ ))
&&&&&&& read line
&&&&&&& #echo $line
&&&&&&&&&&&&&&& commands
&&&&&&&&&&&&&&& echo "line${i} finished."
&&&&&&& } &&6 &
引用来自“宝仔love”的评论这个测试出来也是不同步的!! sh a.sh &
这样三个脚本是同步执行的
<span class="a_vote_num" id="a_vote_num_
将a/b/c.sh三个脚本写到一个shell里面调用,是顺序执行的;但如果a/b/c.sh里面有jar之类的调用,则jar会后台开线程单独执行。
我的看法是:如果a/b/c.sh分别执行都很快,那是否能够并行执行并不重要啊;如果分别执行都很慢,可以考虑将其内容改造成jar(这个亲测可行)或者是sh a.sh后面加&(未亲测,但我想是可以的)。
更多开发者职位上
有什么技术问题吗?
llxi的其它问题
类似的话题博客访问: 567668
博文数量: 89
博客积分: 1216
博客等级: 少尉
技术积分: 1994
注册时间:
优秀是一种习惯
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Python/Ruby
& & 很多人都问我如何写shell脚本,如何实现同时给三台ftp服务器上传文件,如何同时检测三台服务器是否alive等,其实这就是想实现shell的并发。那么shell并发该如何实现呢?& & 下面我就拿这个例子来讲:& & 每次任务都是输出字符“bingfa”,并停留一秒钟,共20次。& & 按照正常思维,脚本应该这样写:[root@station1 ~]# cat a.sh #!/bin/bashfor((i=0;i<20;i++))do sleep 1 echo "bingfa"done[root@station1 ~]# time bash a.sh bingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfareal 0m20.067suser 0m0.016ssys 0m0.031s[root@station1 ~]#可以看到执行此脚本大概用了20秒。那么使用shell并发该怎么写,很多人都会想到后台程序,类似如下:[root@station1 ~]# cat b.sh #!/bin/bashfor((i=0;i<20;i++))do {
echo "bingfa" }&donewait[root@station1 ~]# time bash b.sh bingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfabingfareal 0m1.060suser 0m0.005ssys 0m0.057s[root@station1 ~]#这样写只需花大概一秒钟,可以看到所有的任务几乎同时执行,如果任务量非常大,系统肯定承受不了,也会影响系统中其他程序的运行,这样就需要一个线程数量的控制。下面是我一开始写的代码(是有问题的):[root@station1 ~]# cat c.sh #!/bin/bashexec 6tmpfileecho "1\n1\n1" &>6for((i=0;i<20;i++))do read -u 6 {
echo "$REPLY"
1>&6 }&donewait[root@station1 ~]# time bash c.sh 1111111111111111111111real 0m1.074suser 0m0.012ssys 0m0.031s[root@station1 ~]#可以明显看出是有问题的,我本想控制线程个数为3,但是就算文件描述符6中为空,也会被读取空,然后跳过继续下面的执行,所以使用文件描述符打开一个文件是不行的,然后我就想着使用类似管道的文件来做,下面是我的代码:[root@station1 ~]# cat d.sh #!/bin/bashmkfifo fd2exec 9fd2echo -n -e "1\n1\n1\n" 1>&9for((i=0;i<20;i++))do read -u 9 { #your process
echo "$REPLY"
echo -ne "1\n" 1>&9 } &donewaitrm -f fd2[root@station1 ~]# time bash d.sh 11111111111111111111real 0m7.075suser 0m0.018ssys 0m0.044s[root@station1 ~]#这样就ok了,三个线程运行20个任务,7秒多点。
阅读(10387) | 评论(1) | 转发(5) |
相关热门文章
给主人留下些什么吧!~~
文明上网,理性发言...
请登录后评论。博客访问: 1459747
博文数量: 323
博客积分: 7876
博客等级: 准将
技术积分: 5458
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Python/Ruby
shell并发控制脚本
1.#!/usr/bin/bash
2.# SCRIPT: ptest.sh
3.# AUTHOR: Ray001
5.# REV: 2.0
6.# For STUDY
8.# PURPOSE:
9.# 实现进程并发,提高执行效率,同时能记录每个执行失败的子进程信息
12.#定义并发进程数量
13.PARALLEL=3
14.#定义临时管道文件名
15.TMPFILE=$$.fifo
16.#定义导出配置文件全路径名 该脚本存放的是sleep的时间
17.CMD_CFG=$HOME/cfg/ptest.cfg
18.#定义失败标识文件
19.FAILURE_FLAG=failure.log
22.####################### 函数定义
########################
23.# 中断时kill子进程
24.function trap_exit
26.kill -9 0
30.# 通用执行函数
31.exec_cmd()
33.& & # 此处为实际需要执行的命令,本例中用sleep做示例
34.& & & & sleep ${1}
35.& & if [ $? -ne 0 ]
36.& & then
37.& && &&&echo "命令执行失败"
38.& && &&&return 1
43.trap 'trap_ exit 2' 1 2 3 15
45.#清理失败标识文件
46.rm -f&&${FAILURE_FLAG}
48.#为并发进程创建相应个数的占位
49.mkfifo $TMPFILE #创建FIFO
50.exec 4$TMPFILE
51.rm -f $TMPFILE #为啥要删除??
52.{ #向FIFO写入$PARALLEL个数的换行
53.& & & & count=$PARALLEL
54.& & & & while [ $count -gt 0 ]
55.& & & & do
56.& & & & & & & & echo
57.& & & & & & & & let count=$count-1
58.& & & & done
61.#从任务列表 seq 中按次序获取每一个任务
62.while read SEC
64.& & & & read <&4
65.& & & & (&&exec_cmd ${SEC} || echo ${SEC}>>${FAILURE_FLAG} ; echo
66.done<$CMD_CFG
68.exec 4>&-
70.#并发进程结束后判断是否全部成功
71.if [ -f ${FAILURE_FLAG} ]
73.& && &&&exit 1
75.& && &&&exit 0
阅读(3723) | 评论(0) | 转发(1) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。让天下没有难学的技术
如何写gdb命令脚本
如何写gdb命令脚本
作为UNIX/Linux下使用广泛的调试器,gdb不仅提供了丰富的命令,还引入了对脚本的支持:一种是对已存在的脚本语言支持,比如python,用户可以直接书写python脚本,由gdb调用python解释器执行;另一种是命令脚本(command file),用户可以在脚本中书写gdb已经提供的或者自定义的gdb命令,再由gdb执行。在这篇文章里,我会介绍一下如何写gdb的命令脚本。
(一) 自定义命令
gdb支持用户自定义命令,格式是:
define commandName
其中statement可以是任意gdb命令。此外自定义命令还支持最多10个输入参数:$arg0,$arg1 &#8230;&#8230; $arg9,并且还用$argc来标明一共传入了多少参数。
下面结合一个简单的C程序(test.c),来介绍如何写自定义命令:
#include &stdio.h&
int global = 0;
int fun_1(void)
int fun_a(void)
int a = 0;
printf("%d\n", a);
int main(void)
首先编译成可执行文件:
gcc -g -o test test.c
接着用gdb进行调试:
[root@linux:~]$ gdb test
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
&http://www.gnu.org/software/gdb/bugs/&...
Reading symbols from /data2/home/nanxiao/test...done.
(gdb) b fun_a
Breakpoint 1 at 0x4004d7: file test.c, line 12.
Starting program: /data2/home/nanxiao/test
Breakpoint 1, fun_a () at test.c:12
int a = 0;
fun_a () at test.c:12
0x0500 in main () at test.c:18
可以看到使用bt(backtrace缩写)命令可以打印当前线程的调用栈。我们的第一个自定义命令就是也实现一个backtrace功能:
define mybacktrace
怎么样?简单吧,纯粹复用gdb提供的命令。下面来验证一下:
(gdb) define mybacktrace
Type commands for definition of "mybacktrace".
End with a line saying just "end".
(gdb) mybacktrace
fun_a () at test.c:12
0x0500 in main () at test.c:18
功能完全正确!
接下来定义一个赋值命令,把第二个参数的值赋给第一个参数:
define myassign
set var $arg0 = $arg1
执行一下:
(gdb) define myassign
Type commands for definition of "myassign".
End with a line saying just "end".
&set var $arg0 = $arg1
(gdb) myassign global 3
(gdb) p global
可以看到global变量的值变成了3。
对于自定义命令来说,传进来的参数只是进行简单的文本替换,所以你可以传入赋值的表达式,甚至是函数调用:
(gdb) myassign global fun_1()
(gdb) p global
可以看到global变量的值变成了1。
除此以外,还可以为自定义命令写帮助文档,也就是执行help命令时打印出的信息:
document myassign
assign the second parameter value to the first parameter
执行help命令:
(gdb) document myassign
Type documentation for "myassign".
End with a line saying just "end".
&assign the second parameter value to the first parameter
(gdb) help myassign
assign the second parameter value to the first parameter
可以看到打印出了myassign的帮助信息。
(二) 命令脚本
首先对于命令脚本的命名,其实gdb没有什么特殊要求,只要文件名不是gdb支持的其它脚本语言的文件名就可以了(比如.py)。因为这样做会使gdb按照相应的脚本语言去解析命令脚本,结果自然是不对的。
其次为了帮助用户写出功能强大的脚本,gdb提供了如下的流程控制命令:
(1)条件命令:if...else...end。这个同其它语言中提供的if命令没什么区别,只是注意结尾的end。
(2)循环命令:while...end。gdb同样提供了loop_break和loop_continue命令分别对应其它语言中的break和continue,另外同样注意结尾的end。
另外gdb还提供了很多输出命令。比方说echo命令,如果仅仅是输出一段文本,echo命令特别方便。此外还有和C语言很相似的支持格式化输出的printf命令,等等。
脚本文件的注释也是以#开头的,这个同很多其它脚本语言都一样。
最后指出的是在gdb中执行脚本要使用source命令,例如:“source xxx.gdb”。
(三) 一个完整的例子
最后以一个完整的gdb脚本(search_byte.gdb)做例子,来总结一下本文提到的内容:
define search_byte
if $argc != 3
help search_byte
set $begin_addr = $arg0
set $end_addr = $arg1
while $begin_addr &= $end_addr
if *((unsigned char*)$begin_addr) == $arg2
printf "Find it!The address is 0x%x\n", $begin_addr
loop_break
set $begin_addr = $begin_addr + 1
if $begin_addr & $end_addr
printf "Can't find it!\n"
document search_byte
search a specified byte value(0 ~ 255) during a memory
usage: search_byte begin_addr end_addr byte
这个脚本定义了search_byte命令,目的是在一段指定内存查找一个值(unsigned char类型):需要输入内存的起始地址,结束地址和要找的值。
命令逻辑可以分成3个部分:
(a) 首先判断输入参数是不是3个,如果不是,就输出帮助信息;
(b) 从起始地址开始查找指定的值,如果找到,打印地址值并退出循环,否则把地址加1,继续查找;
(c) 如果在指定内存区域没有找到,打印提示信息。
另外这个脚本还定义了search_byte的帮助信息。
仍然以上面的C程序为例,来看一下如何使用这个gdb脚本:
[root@linux:~]$ gdb test
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
&http://www.gnu.org/software/gdb/bugs/&...
Reading symbols from /data2/home/nanxiao/test...done.
(gdb) p &global
$1 = (int *) 0x600900 &global&
(gdb) p global
(gdb) source search_byte.gdb
(gdb) search_byte 0xx
Find it! The address is 0x600900
(gdb) search_byte 0xx
Can't find it!
可以看到global的值是0,起始地址是0x600900,结束地址是0x600903。在global的内存区域查找0成功,查找1失败。
受篇幅所限,本文只是对gdb命令脚本做了一个粗浅的介绍,旨在起到抛砖引玉的效果。如果大家想更深入地了解这部分知识,可以参考gdb手册的相关章节:Extending GDB ()。最后向大家推荐一个github上的.gdbinit文件:,把这个弄懂,相信gdb脚本文件就不在话下了。
参考文献:
(1)Extending GDB ();
(2)捉虫日记()。
原创文章,转载请注明: 转载自本文链接地址:
一个喜欢研究计算机/通信领域底层技术的工程师,http://chinadtrace.org/站长。
Latest posts by nanxiao ()
Related posts:
(1 votes, average: 1.00 out of 5)
Loading...

我要回帖

更多关于 java执行shell脚本 的文章

 

随机推荐