对bash脚本中的变量值的不同greps始终打印出相同的值

时间:2014-05-07 20:54:29

标签: bash

我有一个群集。在那个集群上我有节点。在那些节点上,我有一组运行(或不运行)的不同进程,我希望看到它的快速概述。我写了这个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

1 个答案:

答案 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}')