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

관련 정보