/proc/ を解析する明示的な方法/stat(与えられた名前フィールドのすべての内容)

/proc/ を解析する明示的な方法/stat(与えられた名前フィールドのすべての内容)

Linux procfsでは、/proc/<pid>/stat2番目の引数として括弧内にプロセス名が含まれています。私が知っている限り(実験を通して)この問題を回避する方法はありません。たとえば、次のことができました。

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

gcc test.c -o 'name) S 42 23'プロセスが誤ってまたは意図的にフィールドを生成することを許可する可能性があり、これは素朴なパーサーを誤解する可能性があります。)

次のいずれかのフィールドを「インポートする必要がある」ため、そのフィールドをスキップする適切な方法が必要です。私はこの行を解析する信頼できる方法を見つけるために長い間検索しましたが、正式な質問や例を見つけることができませんでした。

しかし、私が知っている限り、)これはどの分野でも機能しません。正しいしたがって、一番右のフィールドを見つけるために右から左にスキャンすると、)2番目のフィールドを正しく区切る必要があります。そうですか?これは私に少し不安定なようです()後で新しいフィールドで許可した場合はどうなりますか?)。私が見落としているこのファイルを解析するより良い方法はありますか?

答え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, ...);

関連情報