用ps命令快速弄明白Linux系统任意后台服务的启动流程

问题的提出

Linux上有很多种后台服务,有些我们想对它充分了解,其中一个方面就是,它是怎么启动起来的?为什么启动成这个样子?我哪里配错了?

要弄清如何启动是很麻烦的,首先要弄清楚init程序是sysv版的,还是upstart版的,还是systemd版的。然后还要搜索/etc目录,看是否有相应的启动脚本/配置文件,很麻烦

解决思路

Linux的后台服务,本质上也是一组进程,如果能回溯它的父进程,以及父进程的父进程,则可以绘制出一幅进程家谱。另外,通过每一代父进程的命令行参数,我们还可以获悉每一级流程所用的配置文件,从而明晰服务的整个启动流程

那么怎么获得进程家谱呢?用ps -eaf命令

ps -eaf命令实战

相比常见的ps aux命令,ps -eaf最大的特点是能列出父进程的进程号,即PPID,如此,我们便能一级一级回溯,直到追溯到1号进程init或2号进程kthreadd

下面是一次ps -eaf的输出(有删减),用于调查后台程序PowerAnalyzer的启动流程

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Dec14 ?        00:00:01 /sbin/init
root         2     0  0 Dec14 ?        00:00:00 [kthreadd]
root      1461     1  0 15:29 tty1     00:00:00 /bin/login -f
root      1493  1461  0 15:29 tty1     00:00:00 -bash
root      4953  1493  0 18:26 tty1     00:00:00 /bin/sh /usr/bin/startx --
root      4970  4953  0 18:26 tty1     00:00:00 xinit /etc/X11/xinit/xinitrc -- /etc/X11/xinit/xserverrc :0 -auth /tmp/serverauth.GIIE2AL203
root      4972  4970  2 18:26 tty1     00:00:00 /bin/bash /root/.xsession
root      5007  4972  0 18:26 tty1     00:00:00 /bin/sh /root/appstart.sh
root      5032  5007 26 18:26 tty1     00:00:00 ./PowerAnalyzer

解决步骤

注意看第二列PID和第三列PPID的级联关系,不难发现

  1. PowerAnalyzer的pid是5032,它的ppid是5007,所以父进程是sh appstart.sh
#!/bin/sh
./PowerAnalyzer > /dev/null
  1. appstart.sh的pid是5007,ppid是4972,所以它的父进程是.xsession
chmod +x ~root/appstart.sh
~root/appstart.sh
  1. 同理,.xsession的父进程是xinit,它从/etc/X11/xinit/xinitrc读取用户配置
#!/bin/sh

# /etc/X11/xinit/xinitrc
#
# global xinitrc file, used by all X sessions started by xinit (startx)

# invoke global X session script
. /etc/X11/Xsession
  1. /etc/X11/Xsession的作用是寻找并执行所有名叫.xsession的脚本,而根据进程4972的命令行参数可知,xinit访问的必然是/root/.xsession的内容
  2. 同理,xinit的父进程是startx脚本,里面最终调用的是xinit,为什么startx脚本会获得执行?看下一条
  3. 同理,startx脚本的父进程是交互式bash,它没有命令行参数,那么默认行为是解析HOME目录下的.bashrc
if [ $(tty) == "/dev/tty1" ]; then  # 忽略ssh登录来的pty等伪终端,确保只有本地登录能启动后台服务
    ifconfig eth0 192.168.162.107
    while true; do startx -- ; echo "Again [$?]..."; done
fi
  1. 原来,是.bashrc脚本里的while在循环respawn脚本startx,再由startx最终启动后台服务PowerAnalyzer
  2. 同理,交互式bash的父进程是终端守护程序loginlogin收到用户root从终端tty1发来的登录请求,验证身份后,给予root一个shell——bash
  3. 同理,login守护程序的父进程是init,到根了!

总结

很多时候系统的设计文档是匮乏的,甚至是缺失的,这时候只能通过对系统初始化过程的了解,来反推前人的设计思路,以及当时的约束条件,好为后面的重构打下基础。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值