使用 sudo 运行单个可执行文件会在进程列表中添加两个进程

使用 sudo 运行单个可执行文件会在进程列表中添加两个进程

我编写了一个程序,用于从网络接口捕获数据包。由于它监听网络适配器,因此我需要使用 来运行它sudo。问题是,为什么当我运行它时,它会将两个进程添加到进程列表中?

注意: lwdpi是我的程序

执行前:

ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ ps ax | grep lwdpi
 4665 pts/21   S+     0:00 grep --color=auto lwdpi
ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ 

Execution:
ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ sudo ./lwdpi -i enp5s0
2016:10:26 11:07:29 ::   192.168.1.25   9918  -->     239.1.99.222   9918    UDP
2016:10:26 11:07:29 ::  192.168.1.111   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:30 ::  192.168.1.153   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:30 ::  192.168.1.154   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:30 ::   192.168.1.88   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:30 ::   192.168.1.60   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:37 ::  192.168.1.131  17500  -->  255.255.255.255  17500    UDP
2016:10:26 11:07:37 ::  192.168.1.131  17500  -->    192.168.1.255  17500    UDP
2016:10:26 11:07:37 ::  192.168.1.169   5546  -->     192.168.1.38     53    UDP
2016:10:26 11:07:37 ::  192.168.1.169  30955  -->     192.168.1.38     53    UDP
2016:10:26 11:07:38 ::  192.168.1.110  17500  -->  255.255.255.255  17500    UDP
2016:10:26 11:07:38 ::  192.168.1.110  17500  -->    192.168.1.255  17500    UDP
2016:10:26 11:07:42 ::  192.168.1.169  57189  -->     192.168.1.38     53    UDP
2016:10:26 11:07:42 ::  192.168.1.169  26072  -->     192.168.1.38     53    UDP
2016:10:26 11:07:42 ::  192.168.1.169  41674  -->   199.30.228.113     80    TCP
2016:10:26 11:07:43 ::  192.168.1.169  41676  -->   199.30.228.113     80    TCP
2016:10:26 11:07:43 ::  192.168.1.169   7190  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  30029  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  41678  -->   199.30.228.113     80    TCP
2016:10:26 11:07:43 ::  192.168.1.169  64975  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  12625  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  29973  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  53300  -->     216.58.211.4    443    TCP
2016:10:26 11:07:43 ::  192.168.1.169  41682  -->   199.30.228.113     80    TCP
.
.
.

执行时的进程列表:

ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ ps ax | grep lwdpi
 4685 pts/22   S+     0:00 sudo ./lwdpi -i enp5s0
 4686 pts/22   S+     0:00 ./lwdpi -i enp5s0
 4691 pts/21   S+     0:00 grep --color=auto lwdpi
ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ 

如上所示,执行后,PID = 4685 和 PID = 4686 的进程添加到进程列表中。为什么?我没有在其中调用我的程序!

答案1

当你这样做时:

sudo ./lwdpi -i enp5s0
  • sudo是父进程,它fork(2)是子进程,然后execve(2)使用./lwdpi可执行文件名称执行

  • 子进程lwdpi也是如此sudo

如您所见,这会产生两个过程,一个是,sudo另一个是lwdpi

查看详细信息的最佳方法是检查 PPID(父进程 ID):

ps -eo pid,ppid,args | grep '[l]wdpi'

你会发现lwdpi的父级就是sudo它自己。


以下是sudo的过程模型,来自man sudo

当 sudo 运行命令时,它会调用 fork(2),如上所述设置执行环境,并在子进程中调用 execve 系统调用。主 sudo 进程等待命令完成,然后将命令的退出状态传递给安全策略的 close 函数并退出。

如果配置了 I/O 日志记录插件或安全策略明确要求,则会创建一个新的伪终端(“pty”),并使用第二个 sudo 进程在用户现有的 pty 和运行命令的新 pty 之间传递作业控制信号。这个额外的进程可以暂停和恢复命令等。如果没有它,命令将处于 POSIX 所称的“孤立进程组”中,并且不会收到任何作业控制信号。

特殊情况下,如果策略插件未定义 close 函数且不需要 pty,则 sudo 将直接执行命令,而不是先调用 fork(2)。sudoers 策略插件仅在启用 I/O 日志记录、需要 pty 或启用 pam_session 或 pam_setcred 选项时才定义 close 函数。请注意,在使用 PAM 的系统上,pam_session 和 pam_setcred 默认启用。

答案2

当您使用 启动任何进程时,就会发生这种情况。sudo一个进程是程序sudo,另一个是用 启动的程序sudo,它是第一个进程的子进程。只有当它运行的进程(其子进程)退出时,程序才会退出。以下是我运行时sudo的摘录pstreesudo apt update

    ├─mate-terminal─┬
                    ├─bash───sudo───apt
               child of bash--^      ^--child of sudo

相关内容