【问题标题】:how to enable some commands during run time in a shell script如何在运行时在 shell 脚本中启用某些命令
【发布时间】:2014-11-28 23:20:56
【问题描述】:

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

但有时可能会出现多个 PID 存在于 Java 进程的服务器中。

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

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

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

我的脚本正在获取所有激活的 PID

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

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

之后我运行 Jstack 命令

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

【问题讨论】:

  • 你的问题是什么?
  • 上述命令有什么问题?目前还不是很清楚你的期望是什么。如果您能用示例输入解释当前的情况以及您对输出的期望会有所帮助。
  • 我希望脚本检测 tomcat 和 jboss 有多少进程 ID,因此应该运行 jstack 命令。例如如果只有 PID1,那么 jstack $PID1 > jStack1.txt & 应该运行。如果 PID1 和 PID2 都存在,则 jstack $PID1 > jStack1.txt & 应该为 PID1 运行,而 jstack $PID2 > jStack2.txt & 应该为 PID2 运行。

标签: linux bash shell awk


【解决方案1】:

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

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

【讨论】:

  • ,我在一个 for 循环中做所有事情。我觉得第一个 Jstack 启动 60 秒后没有启用第二个 Jstack。代码就像:#!/bin/bash Sleep1=$1 Sleep2=$(expr $Sleep1 + 60) N=0 for pid in $(ps -ef | grep java| egrep "tomcat|jboss|JBoss" | awk '{print $2}') ;做 testarray[$N]="$pid" (sleep Sleep1;jstack ${testarray[$0]} > jstack.${testarray[$0]}.txt ) (sleep Sleep1;jstack ${testarray[$1]} > jstack .${testarray[$1]}.txt ) #let "N= $N + 1" 完成
【解决方案2】:

您需要将 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

或者可以使用这些方法的某些组合,具体取决于您所追求的。

【讨论】:

  • @dethorpe..是的,您的建议可以很好地获取所有 PID 并运行 Jstack 命令。但是存在一个问题。通过上述命令,如果有 2 个 PID(1 个 tomcat 和 1 个 jboss),则两个 JStack 命令同时运行。但我希望在不同的时间运行它们。当我在 Jstack 命令之前给睡眠时间时,两个 Jstack 命令都在等待中。例如。获得 PID 后,我希望第一个 Jstack 在 60 秒后运行脚本 starta 并在 120 秒后运行第二个 Jstack 命令。该怎么做?
  • 如果我理解正确,您只需要使用两个单独的循环,一个用于 jboss 进程,另一个用于 tomcat(在每个循环中相应地更改 egrep 字符串)。然后根据需要在循环之前和循环之间放置睡眠
  • 我在一个 for 循环中做所有事情。我觉得第一个 Jstack 在第一个 Jstack 启动 60 秒后没有启用。代码就像:#!/bin/bash Sleep1=$1 Sleep2=$(expr $Sleep1 + 60) N=0 for pid in $(ps -ef | grep java| egrep "tomcat|jboss|JBoss" | awk '{print $2}') ;做 testarray[$N]="$pid" (sleep Sleep1;jstack ${testarray[$0]} > jstack.${testarray[$0]}.txt ) (sleep Sleep1;jstack ${testarray[$1]} > jstack .${testarray[$1]}.txt ) #let "N= $N + 1" 完成
猜你喜欢
  • 2019-09-02
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 1970-01-01
  • 2023-01-09
相关资源
最近更新 更多