为什么 sudo 在执行进程之前会分叉?

ssi*_*ice 5 linux unix sudo exec

这个问题可能看起来有点傻,但由于在基于 Unix 的系统中,替换可执行文件的映像是一步完成的,替换当前运行的进程,在函数调用execve(和派生类)中,问题是:

为什么sudo fork()默认情况下在execve更换过程之前?

通过之前的fork,额外的内核元素必须被初始化,虽然fork在一些Unices中已经相当优化,但仍然有一些不可避免的元素必须被初始化。如果fork()默认情况下没有发生,则 PID 空间会增加得更慢。

如果您好奇,可以通过发出如下命令来检查此默认行为

sudo sleep 30
Run Code Online (Sandbox Code Playgroud)

当前的代码 [ 1 ] 遵循起来要复杂得多,因为此后添加了许多功能;但在 Apple [ 2 ]托管的版本中,它的作用非常清楚。

#ifndef PROFILING
    if ((sudo_mode & MODE_BACKGROUND) && fork() > 0)
        exit(0);
    else
        EXEC(safe_cmnd, NewArgv);   /* run the command */
#else
/* Complicated code when profiling is enabled, but we don't care */
Run Code Online (Sandbox Code Playgroud)

我目前正在运行 sudo 版本 1.8.11p2,无论有没有-b开关,它都会以任何一种方式产生睡眠,所以似乎当前的代码变得更加复杂。

我正在寻找一个答案,其中还涵盖了为什么这是默认行为,以及它可以为我们带来哪些优势。

use*_*686 3

Linux上的PID空间可以通过简单的sysctl提高到2 22 ;这真的不是问题...

现在大多数 Linux 发行版都使用 PAM,并且sudo通常也使用 PAM 支持进行编译。除其他外,它pam_open_session()在运行程序之前调用,因此它也必须pam_close_session()从同一进程内调用,因为您的程序不知道它需要这样做(并且可能不允许这样做)。