我有一个群集。在那个集群上我有节点。在那些节点上,我有一组运行(或不运行)的不同进程,我希望看到它的快速概述。我写了这个bash脚本:
#!/usr/bin/env bash
set -o nounset
# Print out the Java process list and store it in a variable
readonly jps=$(jps -v)
# Declare two associative arrays
declare -A up
declare -A pid
# If the process in the in the saved list, set to 1, otherwise 0
up[accumulo_master]=$(echo ${jps} | grep -c 'Dapp=master')
up[accumulo_proxy]=$(echo ${jps} | grep -c 'Dapp=proxy')
# Store the PID of the process
pid[accumulo_master]=$(echo ${jps} | grep 'Dapp=master' | awk '{print $1}')
pid[accumulo_proxy]=$(echo ${jps} | grep 'Dapp=proxy' | awk '{print $1}')
echo Cluster Node Status: $(${wht})${me}$(${off})
echo -----------------------------------------
printf "%-28s %-5s %-5s\n" Component Up? PID
echo -----------------------------------------
for i in "${!up[@]}"
do
printf "%-28s %-5s %-5s\n" $i ${up[$i]} ${pid[$i]};
done |
sort
真实的脚本是相同的,但在up和pid关联数组中有更多的元素。这打印出如下内容:
Cluster Node Status: box1
-----------------------------------------
Component Up? PID
-----------------------------------------
accumulo_master 1 10493
accumulo_proxy 1 10493
问题是,PID始终是相同的 - 它总是打印它遇到的第一个PID,每行重复一次 - 我不明白为什么。如果我更改脚本以便这样的行:
pid[accumulo_master]=$(echo ${jps} | grep 'Dapp=master' | awk '{print $1}')
看起来像这样:
pid[accumulo_master]=$(jps -v | grep 'Dapp=master' | awk '{print $1}')
即。 - 如果我每次都运行jps -v
,它会按预期运行 - 只需更长时间即可运行。
有什么想法吗?
jps -v
的输出示例:
$ jps -v
10493 Main -Dapp=master -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -Djava.net.preferIPv4Stack=true -Xmx128m -Xms128m -XX:OnOutOfMemoryError=kill -9 %p -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -Djava.library.path=/home/hduser/hadoop/lib/native -Dorg.apache.accumulo.core.home.dir=/home/hduser/accumulo -Dhadoop.home.dir=/home/hduser/hadoop -Dzookeeper.home.dir=/home/hduser/zookeeper
16587 Jps -Dapplication.home=/usr/lib/jvm/java-7-openjdk-amd64 -Xms8m
10634 Main -Dapp=tracer -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -Djava.net.preferIPv4Stack=true -Xmx64m -Xms64m -XX:OnOutOfMemoryError=kill -9 %p -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -Djava.library.path=/home/hduser/hadoop/lib/native -Dorg.apache.accumulo.core.home.dir=/home/hduser/accumulo -Dhadoop.home.dir=/home/hduser/hadoop -Dzookeeper.home.dir=/home/hduser/zookeeper
10203 Main -Dapp=monitor -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -Djava.net.preferIPv4Stack=true -Xmx64m -Xms64m -XX:OnOutOfMemoryError=kill -9 %p -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -Djava.library.path=/home/hduser/hadoop/lib/native -Dorg.apache.accumulo.core.home.dir=/home/hduser/accumulo -Dhadoop.home.dir=/home/hduser/hadoop -Dzookeeper.home.dir=/home/hduser/zookeeper
$ jps -v | grep 'Dapp=master'
10493 Main -Dapp=master -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -Djava.net.preferIPv4Stack=true -Xmx128m -Xms128m -XX:OnOutOfMemoryError=kill -9 %p -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -Djava.library.path=/home/hduser/hadoop/lib/native -Dorg.apache.accumulo.core.home.dir=/home/hduser/accumulo -Dhadoop.home.dir=/home/hduser/hadoop -Dzookeeper.home.dir=/home/hduser/zookeeper
$ jps -v | grep 'Dapp=proxy' | awk '{print $1}'
16898
答案 0 :(得分:1)
好的,所以我在发布之后才知道这一点。就像bash一样,这是一个引用问题。
如果你这样做:
readonly jps=$(jps -v)
echo $jps
它将在一行上打印jps -v
的整个多行输出。这意味着awk {print $1}
将总是打印出第一个值 - 因为它是基于行的,并且只有一行。
如果你这样做:
readonly jps=$(jps -v)
echo "$jps"
它打印出多线完整,这正是我所期待的并使一切正常。
我只需要更改脚本,所以这样的行:
pid[accumulo_master]=$(echo ${jps} | grep 'Dapp=master' | awk '{print $1}')
看起来像点击:
pid[accumulo_master]=$(echo "${jps}" | grep 'Dapp=master' | awk '{print $1}')