明确解析/proc/的方法/stat(给定名称字段的任意内容)

明确解析/proc/的方法/stat(给定名称字段的任意内容)

在 linux procfs 中,/proc/<pid>/stat将进程名称作为第二个参数包含在括号中。据我所知(通过实验)这是无法逃脱的。例如,我已经能够创建以下内容

$ gcc test.c -o 'hello) (world'
...
$ cat /proc/9115/stat
9115 (hello) (world) S 8282 9115 ...

(同样gcc test.c -o 'name) S 42 23'可以允许进程意外或故意创建字段,这可能会误导天真的解析器)。

我需要“获取”后面的字段之一,因此需要一种跳过该字段的正确方法。我已经搜索了很长一段时间来找到解析这一行的可靠方法,但未能找到规范的问题或示例。

然而,据我所知,)这在任何领域都无效正确的因此,从右向左扫描以查找最右侧)应该正确界定第二个字段。它是否正确?这对我来说似乎有点不稳定(如果)稍后某个新字段允许怎么办)?有没有更好的方法来解析我忽略的这个文件?

答案1

的格式/proc/<pid>/stat记录在proc(5)联机帮助页。

那里不能是另一个(...)字段,将来也不能添加,因为这会使格式不明确。这很容易看进去。

格式化文件的内核代码/proc/<pid>/stat位于fs/proc/array.c

OP 不会告诉他们正在使用哪种语言。在 perl 中,可以使用类似这样的东西:

my @s = readfile("/proc/$pid/stat") =~ /(?<=\().*(?=\))|[^\s()]+/gs;

请注意s:“命令”字段也可以包含换行符。

答案2

既然所有剩余的字段都是常规数字,为什么不向后计算呢?

例如

$ cat /proc/2086/stat
2086 (hello) (world) S 1893 2086 1893 34816 2175 1077952512 119 0 0 0 0 0 0 0 20 0 1 0 5098 7458816 179 18446744073709551615 94130946203648 94130946231776 140722152072096 0 0 0 0 0 0 1 0 0 17 0 0 0 0 0 0 94130948332368 94130948333696 94130971459584 140722152080859 140722152080880 140722152080880 140722152083432 0
$ awk '{ print $(NF-48) } ' /proc/2086/stat
1893
$

答案3

这就是我解析 stat 文件的方式:

            static char c;
            static long pos = 0;
            fh = fopen(proc_stat_path, "r");
            if(fh == NULL) ...


            // Find the last ")" char in stat file and parse fields thereafter.
            #define RIGHTBRACKET ')'
            while(1)
            {
                    c = fgetc(fh);
                    if (c == EOF) break;
                    if (c == RIGHTBRACKET) pos = ftell(fh);
            }
            fseek(fh, pos, 0);

            fscanf(fh, " %c %d %d" ..., &state, &ppid, ...);

相关内容