对于第一个问题我尝试过:
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。当转换为 a pri
(与-o pri
命令行选项一样)时,它变为 39 - 20 = 19。
当使用-l
命令行选项时,它使用opri
。这意味着 20 + 60 = 80。
因此,比较这两个命令行是完全错误的,因为在一种情况下优先级是 REVERSED 而不是另一种。现在,不要误会我的意思...我知道ps
.ps
我想,这取决于你知道如何运作。幸运的是,在 Linux 下我们有源代码来救援!
我希望你不需要让你的脚本与 Linux 以外的内核兼容......
答案2
- 除了使用
ps
@Alexis Wilke 提到的错误输出选项之外,进程还会一直停止和启动,因此每次运行的计数可能会有所不同。当搜索具有特定优先级的进程时,这种情况不太可能发生,但在计算所有正在运行的进程时,这种情况非常明显。例如:
$ 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
如果您想查看匹配文件的详细目录列表,请删除管道 towc
并添加-ls
到find
的命令行:find /usr/bin/ -perm /u+s -ls
从man find
:
-烫发/模式
为文件设置任何权限位模式。这种形式接受符号模式。 如果您使用符号模式,则必须指定
u
,g
或者 。o
有关一些说明性示例,请参阅示例部分。如果模式中没有设置权限位,则此测试匹配任何文件(这里的想法是与 的行为一致-perm -000
)。