내가 시도한 첫 번째 문제는 다음과 같습니다.
ps -le | tail -n+2 | awk '{if($7>80)print $7}' | wc --lines
그리고
ps -eo pri | tail -n+2 | awk '{if($1>80) print}' | wc --lines
놀랍게도 둘 다 서로 다른 결과를 제공하며 어느 것이 올바른지, 그 이유는 무엇인지 모르겠습니다.
나는 두 번째에 대해 전혀 모른다. 어떤 도움이라도 대단히 감사하겠습니다.
답변1
ps
Linux 패키지에 정의되어 있습니다 procps
.
-c
플래그 -l
와 우선순위를 처리하는 코드가 있습니다 .
if(format_modifiers & FM_c){
PUSH("pri"); PUSH("class");
}else if(format_flags & FF_Ul){
PUSH("ni");
if(personality & PER_IRIX_l) PUSH("priority");
else /* is this good? */ PUSH("opri");
}
따라서 을 사용하면 -c
해당 필드를 얻게 됩니다 pri
.
-l을 사용하면 priority
(IRIX like)를 얻거나 opri
(이게 좋은가요?배너)
즉, 동일한 데이터를 보고 있지 않기 때문에 다른 결과가 나오는 것입니다.
display.c
파일 에서 다음 주석을 볼 수 있습니다.
// "PRI" is created by "opri", or by "pri" when -c is used.
//
// Unix98 only specifies that a high "PRI" is low priority.
// Sun and SCO add the -c behavior. Sun defines "pri" and "opri".
// Linux may use "priority" for historical purposes.
따라서 명령줄에서 -o opri
대신 사용해야 합니다 .-o pri
-o
이러한 우선순위를 비교하려면 명령줄 옵션을 사용할 수 있습니다 .
ps -e -o pri,opri,intpri,priority,ni,pcpu,pid,comm | less
실제로 몇 가지 우선순위가 있습니다. 해당 열을 표시하는 코드는 다음과 같습니다. 항상 값을 사용하며 pp->priority
부호를 변경하거나 숫자를 더하거나 뺍니다. 유일한 직접적인 방법은 priority
("순수한 Linux 우선")입니다.
// legal as UNIX "PRI"
// "priority" (was -20..20, now -100..39)
static int pr_priority(char *restrict const outbuf, const proc_t *restrict const pp){ /* -20..20 */
return snprintf(outbuf, COLWID, "%ld", pp->priority);
}
// legal as UNIX "PRI"
// "intpri" and "opri" (was 39..79, now -40..99)
static int pr_opri(char *restrict const outbuf, const proc_t *restrict const pp){ /* 39..79 */
return snprintf(outbuf, COLWID, "%ld", 60 + pp->priority);
}
// legal as UNIX "PRI"
// "pri_foo" -- match up w/ nice values of sleeping processes (-120..19)
static int pr_pri_foo(char *restrict const outbuf, const proc_t *restrict const pp){
return snprintf(outbuf, COLWID, "%ld", pp->priority - 20);
}
// legal as UNIX "PRI"
// "pri_bar" -- makes RT pri show as negative (-99..40)
static int pr_pri_bar(char *restrict const outbuf, const proc_t *restrict const pp){
return snprintf(outbuf, COLWID, "%ld", pp->priority + 1);
}
// legal as UNIX "PRI"
// "pri_baz" -- the kernel's ->prio value, as of Linux 2.6.8 (1..140)
static int pr_pri_baz(char *restrict const outbuf, const proc_t *restrict const pp){
return snprintf(outbuf, COLWID, "%ld", pp->priority + 100);
}
// not legal as UNIX "PRI"
// "pri" (was 20..60, now 0..139)
static int pr_pri(char *restrict const outbuf, const proc_t *restrict const pp){ /* 20..60 */
return snprintf(outbuf, COLWID, "%ld", 39 - pp->priority);
}
// not legal as UNIX "PRI"
// "pri_api" -- match up w/ RT API (-40..99)
static int pr_pri_api(char *restrict const outbuf, const proc_t *restrict const pp){
return snprintf(outbuf, COLWID, "%ld", -1 - pp->priority);
}
그래서 우리는 본다
- "priority" - 직접 Linux 우선순위(-100 ~ 39)
- "intpri", "opri" - Linux 우선순위 + 60(-40 ~ 99)
- "pri_foo" - Linux 우선순위 - 20(-120 ~ 19)
- "pri_bar" - Linux 우선순위 + 1(-99~40)
- "pri_baz" - Linux 우선순위 + 100(1~140)
- "pri" -- 39 - Linux 우선 순위(0~139, 반전)
- "pri_api" -- -1 - Linux 우선순위(-40 ~ 99, 반전)
마지막 두 개("pri" 및 "pri_api")는 Unix에서 "불법"으로 간주됩니다.
이 데이터의 출처는 /proc/<id>/stat
파일에서 찾을 수 있습니다. sscanf()
프로세스 ID와 이름(대괄호 사이)을 건너뛴 후 다음 호출을 통해 파일을 읽고 텍스트 줄을 구문 분석합니다.
우리는 하나의 매개변수가 임을 알 수 있습니다 &P->priority
. 따라서 18번째 매개변수(ID와 이름을 생략하고 16번째 매개변수)는 1로 시작합니다.
num = sscanf(S,
"%c "
"%d %d %d %d %d "
"%lu %lu %lu %lu %lu "
"%Lu %Lu %Lu %Lu " /* utime stime cutime cstime */
"%ld %ld "
"%d "
"%ld "
"%Lu " /* start_time */
"%lu "
"%ld "
"%lu %"KLF"u %"KLF"u %"KLF"u %"KLF"u %"KLF"u "
"%*s %*s %*s %*s " /* discard, no RT signals & Linux 2.1 used hex */
"%"KLF"u %*u %*u "
"%d %d "
"%lu %lu",
&P->state,
&P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid,
&P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt,
&P->utime, &P->stime, &P->cutime, &P->cstime,
&P->priority, &P->nice,
&P->nlwp,
&P->alarm,
&P->start_time,
&P->vsize,
&P->rss,
&P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack, &P->kstk_esp, &P->kstk_eip,
/* P->signal, P->blocked, P->sigignore, P->sigcatch, */ /* can't use */
&P->wchan, /* &P->nswap, &P->cnswap, */ /* nswap and cnswap dead for 2.4.xx and up */
/* -- Linux 2.0.35 ends here -- */
&P->exit_signal, &P->processor, /* 2.2.1 ends with "exit_signal" */
/* -- Linux 2.2.8 to 2.5.17 end here -- */
&P->rtprio, &P->sched /* both added to 2.5.18 */
);
데이터를 읽는 예는 다음과 같습니다 libprocps
.
$ cat /proc/1/stat
1 (systemd) S 0 1 1 0 -1 4194560 188421 1692322137 105 191899 1093 466 35079020 6527486 20 0 1 0 2 341475328 1402 18446744073709551615 1 1 0 0 0 0 671173123 4096 1260 0 0 0 17 2 0 0 3606 0 0 0 0 0 0 0 0 0 0
따라서 프로세스 1의 Linux 우선순위는 20입니다. pri
( -o pri
명령줄 옵션에서와 같이) 로 변환하면 39 - 20 = 19가 됩니다.
-l
명령줄 옵션을 사용할 때 사용됩니다 opri
. 이는 20 + 60 = 80을 의미합니다.
따라서 이 두 명령줄을 비교하는 것은 완전히 잘못된 것입니다. 한 경우에는 우선순위가 반전되고 다른 경우에는 우선순위가 반전되지 않기 때문입니다. 오해하지 마세요... 알겠습니다 ps
. ps
작동 방법을 어떻게 아는지에 달려 있습니다. 운 좋게도 Linux에는 구조할 수 있는 소스 코드가 있습니다!
스크립트를 Linux 이외의 커널과 호환되도록 만들 필요가 없기를 바랍니다...
답변2
- @Alexis Wilke가 언급한 오류 출력 옵션을 사용하는 것 외에도
ps
프로세스가 항상 중지되고 시작되므로 실행마다 개수가 달라질 수 있습니다. 특정 우선순위를 가진 프로세스를 검색할 때는 이런 일이 발생할 가능성이 낮지만 실행 중인 모든 프로세스를 계산할 때 매우 눈에 띕니다. 예를 들어:
$ for i in {1..10} ; do ps hax | wc -l ; sleep 1; done
994
1032
1031
1023
1009
997
1037
1001
1038
1034
그런데 의 헤더를 원하지 않으면 ps
인쇄하지 말라고 지시하세요. 필요 없음 ps ... | tail -n+2
. 대신 사용하십시오 ps h <other options>
.
find
-perm
setuid 비트를 포함하여 특정 권한이 있는 파일을 찾는 옵션입니다 . 예를 들어
$ find /usr/bin/ -perm /u+s | wc -l
34
일치하는 파일의 자세한 디렉터리 목록을 보려면 파이프를 제거하고 명령줄 에 wc
추가하세요 .-ls
find
find /usr/bin/ -perm /u+s -ls
에서 man find
:
-파마/모드
파일에 대한 권한 비트 패턴을 설정합니다. 이 형식은 기호 패턴을 허용합니다. 기호 모드를 사용하는 경우
u
,g
또는 를 지정해야 합니다.o
몇 가지 예시를 보려면 예제 섹션을 참조하세요. 패턴에 권한 비트가 설정되지 않은 경우 이 테스트는 모든 파일과 일치합니다(여기서 아이디어는 의 동작과 일치한다는 것입니다-perm -000
).