目前我已经设法这样做了:
root@server:~# for i in $(netstat -lp | grep java | awk '{print $7}' | awk -F '/' '{print $1}' | sort | uniq); do ap=$(ps p $i | grep -v PID | grep activemq | awk '{print $1}'); done; netstat -lp | grep $ap
tcp 0 0 localhost:32000 *:* LISTEN 23059/java
tcp6 0 0 HPM.DMZ:61616 [::]:* LISTEN 23059/java
tcp6 0 0 [::]:8161 [::]:* LISTEN 23059/java
tcp6 0 0 [::]:36168 [::]:* LISTEN 23059/java
它检查所有属于开放网络端口的进程ID,检查它是否是tomcat实例“activemq”。
还有更好的建议吗?
答案1
for i in $(ps aux | awk '/activemq/ {print $2}' | sort -gu); do netstat -lp | grep $i; done
tcp 0 0 localhost:32000 *:* LISTEN 23059/java
tcp6 0 0 HPM.DMZ:61616 [::]:* LISTEN 23059/java
tcp6 0 0 [::]:8161 [::]:* LISTEN 23059/java
tcp6 0 0 [::]:36168 [::]:* LISTEN 23059/java
更短,但是它调用网络状态多次。
答案2
这个会更简洁一些;它检查哪些是名为“ .*activemq.*
”的进程的 pid,然后检查它们打开的端口:
netstat -lp | grep $(ps aux | awk '/[a]ctivemq/ {print $2}')
如果需要,您可以添加 uniq 过滤器:
netstat -lp | grep $(ps aux | awk '/[a]ctivemq/ {print $2}' | sort -u)
根据乔的评论进行编辑:
Joe Nazz 写道:
它不起作用。“”“$(ps aux | awk '/[a]ctivemq/ {print $2}' | sort -u)”””的结果为多行,grep 无法识别。它显示“没有这样的文件或目录...” –
你是对的,如果有多个进程,我们需要在 grep 的正则表达式中做更多的工作。
所以为了保持我的只运行一次 netstat命令,表达式应该类似于:
~# netstat -lp | grep $(ps aux | awk '/[a]pache/ {a=a"\|"$2} END { sub(/^../,"",a); print "("a")"}')
该命令创建一个正则表达式来匹配 apache 的每个 pid(我使用 apache2 作为多实例进程来满足您的需求)。正如您将在以下表达式中看到的那样,创建的正则表达式会尝试匹配 apache 的每个 pid:
~# ps aux | awk '/[a]pache/ {a=a"\|"$2} END { sub(/^../,"",a); print "("a")"}'
(7335\|7336\|7337\|7338\|7339\|8733\|8744\|13418\|13421\|23126)
– Joe Nazz 写道:
[...] 但括号里的单个“a”是什么意思呢?——
关于你为什么在正则表达式中使用 [a] 的问题,这是一个非常古老的技巧,可以避免匹配正则表达式本身创建的过程。以下示例不言自明:
~# ps aux | grep foo
root 10932 0.0 0.0 9608 868 pts/0 S+ 11:42 0:00 grep foo
~# ps aux | grep "[f]oo"
~#
PS:如果你觉得这个答案有帮助,请不要放弃投票
答案3
这将检索“activemq”pid,测试是否返回一个pid,然后运行一次netstat。
pids=`ps -eo 'pid,args' | awk '/activemq/ && !/awk/ {print $1}'`
test -n "${pids}" && netstat -lp | egrep -w "(`echo ${pids} | tr ' ' '|'`)"