我有几个testing脚本,每个脚本都运行一个testingPHP应用程序。 每个脚本永远运行。
所以, cat.sh , dog.sh和foo.sh都运行一个PHP脚本。 每个shell脚本在一个循环中运行PHP应用程序,所以它会永远运行,每次运行后都会hibernate。
我想弄清楚如何在同一时间并行运行脚本。 在标准输出/术语窗口中查看PHP应用程序的输出。
我想,做下面的事情可能会起作用:
foo.sh > &2 dog.sh > &2 cat.sh > &2
在一个shell脚本中就足够了,但它不起作用。
foo.sh, runs foo.php once, and it runs correctly dog.sh, runs dog.php in a never ending loop. it runs as expected cat.sh, runs cat.php in a never ending loop *** this never runs!!!
看来shell脚本永远不会运行cat.sh 如果我在单独的窗口/术语中自行运行cat.sh ,它将按预期运行。
有没有人有任何想法,我怎样才能让这些脚本并行运行?
您当前的设置是按顺序运行您的命令。 第一个运行, 并完成 ,允许第二个启动。 第二个永远不会结束,所以第三个永远不会有机会开始。
尝试这个:
foo.sh >foo.out 2>foo.err & dog.sh >dog.out 2>dog.err & cat.sh >cat.out 2>cat.err &
这将告诉每个命令在后台运行,并将其输出和错误信息发送到文件。 当命令在后台运行时,它从当前会话中分离出来,并允许运行下一个命令。 将&符号( & )作为行的最后一个字符是很重要的。 否则,可能无法正确识别。
或者,让每个shell脚本运行相关的.php脚本,显然是使用与上面相同的语义调用的。 在这种情况下,你的foo.sh可能包含:
#!/bin/bash php foo.php >foo.out 2>foo.err &
最后,如果你需要真正的并行操作,请查看GNU并行 。
注意:如果你真的想要输出到屏幕/terminal,你可以离开输出redirect:
foo.sh &
但是请记住,同时运行多个命令可能会导致输出混乱(您现在可能知道哪个输出或哪个错误来自哪个命令),如果注销,输出无处可去。
这可以通过并行命令完成。
美丽的例子: 平行
[me@neo]<bash><~> 19 05:51 Tue Mar 05 > man -f parallel parallel (1) - run programs in parallel
–
parallel -j 3 -- "sh foo.sh" "sh dog.sh" "sh cat.sh"
这将同时启动3个脚本。
parallel sh -c "echo hi; sleep 2; echo bye" -- 1 2 3
这将默认启动许多相同命令的进程,具体取决于cpu的数量。
parallel -j 3 sh -c "echo hi; sleep 2; echo bye" -- 1 2 3
这将强制执行3个进程,即使你只有2个CPU。
例:
[me@neo]<bash><~> 31 06:09 Tue Mar 05 > parallel -j 10 sh -c "echo Hello World; sleep 3; echo Good morning" -- $(seq 1 10) Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Good morning Good morning Good morning Good morning Good morning Good morning Good morning Good morning Good morning Good morning
克里斯对大多数脚本都有很好的总体思路:用&结束每个命令,然后他们会进入后台。 这就是说,这是我为了一些更高端的任务而保留的东西。 让我来介绍一下我的方便的工具箱脚本parallel-exec.pl
#!/usr/bin/perl use threads; use Thread::Queue; my @workers; my $num_threads = shift; my $dbname = shift; my $queue = new Thread::Queue; for (0..$num_threads-1) { $workers[$_] = new threads(\&worker); print "TEST!\n"; } while ($_ = shift @ARGV) { $queue->enqueue($_); } sub worker() { while ($file = $queue->dequeue) { system ('./parser.pl', $dbname, $file); } } for (0..$num_threads-1) { $queue->enqueue(undef); } for (0..$num_threads-1) { $workers[$_]->join; }
稍微调整一下,你可以改变线程的数量,提供一个命令数组等等。现在,这需要在命令行中指定的线程数量,数据库名称以及要导入的文件列表,然后为每个运行指定数字的文件生成一个实例。
或..你可以这样做:
threads=20 tempfifo=$PMS_HOME/$$.fifo trap "exec 1000>&-;exec 1000<&-;exit 0" 2 mkfifo $tempfifo exec 1000<>$tempfifo rm -rf $tempfifo for ((i=1; i<=$threads; i++)) do echo >&1000 done for ((j=1; j<=1000; j++)) do read -u1000 { echo $j echo >&1000 } & done wait echo "done!!!!!!!!!!"
每次它并行运行20个线程。
希望它帮助:)