1)有多少进程的优先级高于80? 2) /usr/bin 中有多少个设置了 setuid 位的可执行文件?

1)有多少进程的优先级高于80? 2) /usr/bin 中有多少个设置了 setuid 位的可执行文件?

对于第一个问题我尝试过:

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

  1. 除了使用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>

  1. find-perm选项可以查找具有特定权限的文件,包括 setuid 位。例如
$ find /usr/bin/ -perm /u+s | wc -l
34

如果您想查看匹配文件的详细目录列表,请删除管道 towc并添加-lsfind的命令行:find /usr/bin/ -perm /u+s -ls

man find

-烫发/模式

为文件设置任何权限位模式。这种形式接受符号模式。 如果您使用符号模式,则必须指定u, g 或者 。o有关一些说明性示例,请参阅示例部分。如果模式中没有设置权限位,则此测试匹配任何文件(这里的想法是与 的行为一致-perm -000)。

相关内容