私が試した最初の問題は次のとおりです。
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
驚くべきことに、どちらも異なる結果をもたらし、どちらが正しいか、その理由は何であるかわかりません。
私は2回目について全く知りません。どんな助けでも大変感謝します。
ベストアンサー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、反転)
最後の2つ(「pri」と「pri_api」)は、Unixでは「違法」と見なされます。
このデータのソースは/proc/<id>/stat
ファイルにあります。sscanf()
プロセスIDと名前(括弧の間)をスキップした後、次の呼び出しでファイルを読み取り、テキスト行を解析します。
1つのパラメータがあることがわかります&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を意味します。
したがって、これら2つのコマンドラインを比較することは完全に間違っています。ある場合には優先順位が反転され、他の場合には優先順位が反転されないためです。誤解しないでください...わかりましたps
。ps
どのように動作するかを知っているに依存します。幸いなことに、Linuxには構造的なソースコードがあります!
スクリプトをLinux以外のカーネルと互換性があるようにする必要はありません。