版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/10km/article/details/100603320
如下是我的项目中创建的一个java系统服务在通过systemctl status
显示的服务状态
$ systemctl status facelog
● facelog.service - facelog service
Loaded: loaded (/etc/systemd/system/facelog.service; enabled; vendor preset: enabled)
Active: active (running) since 六 2019-09-07 17:25:29 CST; 27min ago
Docs: https://gitee.com/l0km/facelog
Process: 894 ExecStop=/home/gyd/workspace/facelog-delivery/facelog stop (code=exited, status=0/SUCCESS)
Main PID: 1088 (facelog)
CGroup: /system.slice/facelog.service
├─1088 /bin/bash /home/gyd/workspace/facelog-delivery/facelog start --hup
├─1482 /bin/bash ./facelog-service/target/start_facelog_server.sh
└─1494 java -jar facelog-service-2.4.2-standalone.jar
9月 07 17:25:29 gyd systemd[1]: Stopped facelog service.
9月 07 17:25:29 gyd systemd[1]: Started facelog service.
9月 07 17:25:29 gyd facelog[1088]: 启动 facelog 服务(start facelog service)...
9月 07 17:25:30 gyd facelog[1088]: 执行 tail -f /home/gyd/workspace/facelog-delivery/facelog.out 查看控制台输出
可以发现服务产生了三个进程,进程ID分别为1088,1482,1494,从左到右为父/子进程关系.如果想通过netstat命令根据PID查找服务所占用的端口,就需要最右的java子进程ID。
但是通过systemctl show --property MainPID <service name>
命令只能获取最左边的父进程ID. 怎么样通过这个MainPID获取实际工作的子进程ID呢,ps的 -g
选项可以根据PID过程要显示的所有属于指定PID的进程及子进程,比如:
$ ps --forest -o pid,cmd -g 1088
PID CMD
1088 /bin/bash /home/gyd/workspace/facelog-delivery/facelog start --hup
1482 \_ /bin/bash ./facelog-service/target/start_facelog_server.sh
1494 \_ java -jar facelog-service-2.4.2-standalone.jar
最后一行就是最后的子进程
这样就好办了。比如下面的过程可以获取指定服务的占用的端口:
#!/bin/bash
# 获取服务的MainPID,$service_name 为服务名称
main_pid="$(systemctl show $service_name --property=MainPID)"
main_pid=${main_pid##*=}
# ps 命令获取最下层的子进程ID
spid=$(ps -o pid -g $main_pid | sed -e '1d' -e '$!d')
# 输出端口号
netstat -nlp 2>/dev/null|grep $spid|grep -E ':[[:digit:]]+' -o | sed 's/://g'