Linux 如何在shell脚本的运行时启用某些命令

Linux 如何在shell脚本的运行时启用某些命令,linux,bash,shell,awk,Linux,Bash,Shell,Awk,我已经编写了1个shell脚本来为特定的进程ID(PID)运行Jstack命令 但是,有时可能会发生多个PID出现在一个ServerforJava进程中 在这种情况下,我希望运行许多Jstack命令,将各自的PID作为命令的输入 如果一个应用程序有两个服务器(一个tomcat和一个jboss),那么我需要运行两个JStack命令来捕获两个进程的两个不同日志 那么,如何处理或检查,以便脚本自动决定java进程中有多少PID r,并运行脚本中编写的命令呢 我的脚本正在使所有PID通过 PID1=$(

我已经编写了1个shell脚本来为特定的进程ID(PID)运行Jstack命令

但是,有时可能会发生多个PID出现在一个ServerforJava进程中

在这种情况下,我希望运行许多Jstack命令,将各自的PID作为命令的输入

如果一个应用程序有两个服务器(一个tomcat和一个jboss),那么我需要运行两个JStack命令来捕获两个进程的两个不同日志

那么,如何处理或检查,以便脚本自动决定java进程中有多少PID r,并运行脚本中编写的命令呢

我的脚本正在使所有PID通过

PID1=$(ps -ef|grep java|grep jboss| awk '{print $2}' )

在这之后,我将运行Jstack命令作为

jstack $PID1 > jStack1.txt & and jstack $PID2 > jStack2.txt &

您需要将PID组合成一个列表并循环它们

这样可以为每个pid获取一个单独的文件:

for pid in $( ps -ef | egrep "tomcat|jboss" | awk '{print $2}')
do
    jstack $pid > jstack.$pid.txt
done
继续您上次的评论

我不确定你想对数组和循环中的多个jstack调用做什么,因为它会对每个pid迭代一次,不会在循环中给你两个pid,而且$0和$1索引没有意义(你是说仅仅是0和1吗?),你每次都使用$N,但是它的增量被注释掉了,所以将保持为0

如果您确定只能有两个PID,一个用于tomcat,一个用于jboss,那么添加睡眠的初始代码就可以:

#!/bin/bash 
Sleep1=$1 

# sleep for the first requested time
sleep $Sleep1

# do the tomcat jstack
PID1=$(ps -ef | grep java| grep tomcat | awk '{print $2}')
jstack $PID1 > jstack.tomcat.$PID1.txt

# sleep for another 60secs
sleep 60

# do the jboss jstack
PID2=$(ps -ef | grep java| egrep "jboss|JBoss" | awk '{print $2}')
jstack $PID2 > jstack.jboss.$PID1.txt
如果可以有多个tomcat进程和多个jboss进程,那么您需要两个循环:

#!/bin/bash 
Sleep1 = $1 

# sleep for the first requested time
sleep = $Sleep1 

# Do all the tomcat jstacks
for pid in $(ps -ef | grep java| grep "tomcat" | awk '{print $2}')
do 
    jstack $pid > jstack.tomcat.${pid}.txt ) 
done

# sleep for another 60secs
sleep 60

# Do all the jboss jstacks
for pid in $(ps -ef | grep java| egrep "jboss|JBoss" | awk '{print $2}')
do 
    jstack $pid > jstack.jboss.${pid}.txt ) 
done

或者这些方法的某些组合可以根据您的具体目标来使用。

要获得pid,您可以使用
pgrep
而不是
ps/grep/grep/awk

for pid in $(pgrep -f "tomcat|jboss")
do
  jstack $pid >> jStack1.txt 
done

你的问题是什么?上面的命令有什么问题?你的期望值不是很清楚。如果你能用示例输入解释当前的情况,以及你在输出中所期望的情况,那会有所帮助。我希望脚本能够检测tomcat和jboss有多少进程ID,并相应地运行jstack命令。如果只有PID1,那么jstack$PID1>jStack1.txt&应该运行。如果PID1和PID2都存在,那么jstack$PID1>jstack 1.txt&应该为PID1运行,jstack$PID2>jstack 2.txt&应该为PID2运行。@dethorpe..Ya您的建议可以很好地获得所有的PIDs并运行jstack命令。但是有一个问题。通过上面的命令,如果有2个PID(1个tomcat和1个jboss),那么两个JStack命令一次都在运行。但我希望在不同的时间运行它们。当我在Jstack命令之前给睡眠时间时,两个Jstack命令都在等待。在获得PID后,我希望第一个Jstack在60秒后运行,脚本starta和第二个Jstack命令在120秒后运行。如何做到这一点?如果我理解正确,您只需要使用两个独立的循环,一个用于jboss进程,另一个用于tomcat(相应地更改每个进程中的egrep字符串)。然后把睡眠放在循环之前和循环之间,因为你想在一个for循环中做任何事情。我觉得第一个Jstack启动60秒后,第1个Jstack没有启用。代码如下:#/bin/bash Sleep1=$1 Sleep2=$(expr$Sleep1+60)N=0表示$(ps-ef | grep java | egrep“tomcat | jboss | jboss”| awk'{print$2}');do testarray[$N]=“$pid”(sleep Sleep1;jstack${testarray[$0]}>jstack.${testarray[$0]}.txt)(sleep Sleep1;jstack${testarray[$1]}>jstack.${testarray[$1]}.txt)#让“N=$N+1”完成,我在一个for循环中做每件事。我觉得第二个Jstack在第一个Jstack启动60秒后没有启用。代码如下:#/bin/bash Sleep1=$1 Sleep2=$(expr$Sleep1+60)N=0表示$(ps-ef | grep java | egrep“tomcat | jboss | jboss”| awk'{print$2}');do testarray[$N]=“$pid”(sleep Sleep1;jstack${testarray[$0]}>jstack.${testarray[$0]}.txt)(sleep Sleep1;jstack${testarray[$1]}>jstack.${testarray[$1]}.txt)#让“N=$N+1”完成
for pid in $(pgrep -f "tomcat|jboss")
do
  jstack $pid >> jStack1.txt 
done