运行具有多个程序动态并行的Shell脚本

时间:2017-12-08 14:26:21

标签: bash shell parallel-processing

我有一个shell脚本,每隔n秒捕获JVM的Process ID, CPU and Memory并将输出写入文件。以下是我的代码:

JVM="aaa001_bcdefx01"
systime=$(date +"%m-%d-%y-%T")
for i in {1..10}
do
PID=`ps -auxwww | grep "jdk" |  grep $JVM | grep -v grep | cut -c -30 | awk '{print  $2}'`
MEM=`ps -auxwww | grep "jdk" |  grep $JVM | grep -v grep | cut -c -30 | awk '{print  $4 }'`
CPU=`ps -auxwww | grep "jdk" |  grep $JVM | grep -v grep | cut -c -30 | awk '{print  $3 }'`
printf '%-5s %-20s %-20s %-20s %-20s \n' "$systime $JVM $PID $CPU $MEM "  >> $LOGFILE
sleep 5
done

当我在该服务器中只有一个JVM时,运行完全正常。如果我有一个服务器的多个JVM,我如何并行执行相同的脚本并获取详细信息。

我找了一些解决方案,发现在脚本中使用了&但是无法理解如何在我的上面脚本中实现它。假设我有5个JVM。如何并行运行脚本并为所有以下JVM并行获取统计信息。请指导。任何帮助将不胜感激。

JVM="aaa001_bcdefx01"
JVM="aaa002_bcdefx01"
JVM="aaa003_bcdefx01"
JVM="aaa004_bcdefx01"
JVM="aaa005_bcdefx01"

2 个答案:

答案 0 :(得分:0)

如何使用子shell?

每个JVM shell脚本都应该放在'('和')'里面。放'&'最后,以便它在后台执行。

这里给出了一个例子。

#!/bin/bash
echo > testfile.txt
echo "execute subshell 1"
(
#JVM 1 should go here
sleep 10
echo "subshell 1" >> testfile
)&

echo "execute subshell 2"
(
#JVM 2 should go here
sleep 10
echo "subshell 2" >> testfile
)&

echo "execute subshell 3"
(
#JVM 3 should go here
sleep 10
echo "subhsell 3" >> testfile
)&

这里每个子shell在等待10秒后将数据写入testfile.txt。

答案 1 :(得分:0)

GNU Parallel是为这种东西而制作的

doit() {
  JVM="$1"
  systime=$(date +"%m-%d-%y-%T")
  for i in {1..10}
  do
    PID=`ps -auxwww | grep "jdk" |  grep $JVM | grep -v grep | cut -c -30 | awk '{print  $2}'`
    MEM=`ps -auxwww | grep "jdk" |  grep $JVM | grep -v grep | cut -c -30 | awk '{print  $4 }'`
    CPU=`ps -auxwww | grep "jdk" |  grep $JVM | grep -v grep | cut -c -30 | awk '{print  $3 }'`
    printf '%-5s %-20s %-20s %-20s %-20s \n' "$systime $JVM $PID $CPU $MEM "
    sleep 5
  done
}
export -f doit
parallel -j0 --linebuffer --tag doit ::: aaa00{1..5}_bcdefx01 >> $LOGFILE

该功能基本上是您的代码。更改是它将JVM作为参数并打印到stdout(标准输出)。 GNU Parallel使用参数aaa00N_bcdefx01调用函数,其中N = 1..5,并将输出保存到$ LOGFILE。只要有一个完整的行,它就会使用--linebuffer来传递输出,从而保证你不会从一个进程混合另一个进程的一行进行半行。 --tag以JVM为前缀。