我编写了一个程序,用于从网络接口捕获数据包。由于它监听网络适配器,因此我需要使用 来运行它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
的摘录pstree
sudo apt update
├─mate-terminal─┬
├─bash───sudo───apt
child of bash--^ ^--child of sudo