[关闭]
@CptZhao 2014-11-13T09:17:42.000000Z 字数 2737 阅读 1153

动手编写ps命令

cmd_diy /proc


This project is still in progress!
Jump in: zhaonanyu/ps_cmd


1. 了解ps lf命令

此次的目的是编写一个高仿的ps lf命令

首先来看一下ps lf命令都能显示什么信息呢?

  • F - flags associated with the process, see the PROCESS FLAGS section
  • UID - effective user ID
  • PID
  • PPID
  • PRI - priority
  • NI - nice
  • VSZ - virtual memory size of the process in KB. Device mappings are currently excluded; this is subject to change.
  • RSS - resident set size, the non-swapped physical memory that a task has used.
  • WCHAN - name of the kernel function in which the process is sleeping, a"-"if the process is running, or a "*"if the process is multi-threaded and ps is not displaying threads.
  • STAT - multi-character process state
  • TTY - controlling tty
  • TIME - cumulative CPU time, "[DD-]HH:MM:SS" format
  • COMMAND - command name(only the excutable name).

那么这么多要显示的信息是从哪里获得的呢?
我们使用strace命令来观察一下ps命令使用的系统调用:

  1. $strace -o ~/strace_ps ps

该命令是将strace命令得到的信息保存成文件,下面是得到的信息:

  1. stat("/proc/1", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
  2. open("/proc/1/stat", O_RDONLY) = 6
  3. read(6, "1 (init) S 0 1 1 0 -1 4219136 55"..., 1024) = 198
  4. close(6) = 0
  5. open("/proc/1/status", O_RDONLY) = 6
  6. read(6, "Name:\tinit\nState:\tS (sleeping)\nT"..., 1024) = 786
  7. close(6) = 0
  8. stat("/proc/2", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
  9. open("/proc/2/stat", O_RDONLY) = 6
  10. read(6, "2 (kthreadd) S 0 0 0 0 -1 213817"..., 1024) = 168
  11. close(6) = 0
  12. open("/proc/2/status", O_RDONLY) = 6
  13. read(6, "Name:\tkthreadd\nState:\tS (sleepin"..., 1024) = 554
  14. close(6)

当然上面这只是我们用strace得到的strace_ps文件的一部分,参阅strace的结果可以了解到ps命令在读取/proc文件夹中的/proc/1等/proc文件夹中的数字文件夹的某些文件,仔细看事实上它(ps命令)在不停地读取两个文件:stat和status文件。

来看一下/proc/[pid]文件夹中的文件以及文件夹吧:

pic here

由刚才得到的strace_ps文件了解到:

ps命令在不停地读取stat和status文件

先来看一下stat文件的内容吧

  1. $cat /proc/1/stat

stat的内容:

  1. 1 (init) S 0 1 1 0 -1 4219136 52950 1012828 29 782 24 206 1204 789 20 0 1 0 3 34713600 801 18446744073709551615 1 1 0 0 0 0 0 4096 536962595 18446744073709551615 0 0 17 0 0 0 4 0 0 0 0 0 0 0 0 0 0

诶要我去这都啥?不要着急,接下来就来解释


2. 了解stat文件的内容

Linux下面想了解系统中的某些信息是如何存储的当然就是使用man命令咯。

  1. $man proc

往下面找,找到:/proc/[pid]/stat

  1. /proc/[pid]/stat
  2. Status information about the process. This is used by ps(1). It is defined in /usr/src/linux/fs/proc/array.c.
  3. The fields, in order, with their proper scanf(3) format specifiers, are:
  4. pid %d (1) The process ID.

下面就是stat文件每个参数的相关解释,stat文件包含很多进程执行过程中相关的信息,而我们并不需要解析出stat中全部的信息,先从简单的入手做一个显示pid ppid STAT和COMMAND的简易ps命令吧。
先找到上面需要的四个参数的信息:

  1. pid %d (1) The process ID.
  2. comm %s (2) The filename of the executable, in parentheses. This is visible
  3. whether or not the executable is swapped out.
  4. state %c (3) One character from the string "RSDZTW" where R is running, S is
  5. sleeping in an interruptible wait, D is waiting in uninterruptible disk
  6. sleep, Z is zombie, T is traced or stopped (on a signal), and W is pag
  7. ing.
  8. ppid %d (4) The PID of the parent.

回来看一下stat的内容:

pic here stat file

上面的man proc中可以了解到:pid是第一个参数,comm是第二个参数,state是第三个参数,ppid是第四个参数。也就是说对于pid:2072的进程,comm为bash,state为S(Sleeping),其父进程号为2685。
从上面的man proc中可以了解到stat文件总共包含了44个和某一指定进程相关的信息,如刚才所言不着急了解全部信息,先动手写一个简单的ps命令。


3. 动手编写ps命令(第一版)

先简单来说一下咱们自制的ps命令的流程:

Created with Raphaël 2.1.2Start读取/proc/[pid]文件夹读取/proc/[pid]文件夹中的stat文件解析并显示stat文件的内容End
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注