我编写了一个程序来捕获来自网络接口的数据包。当它侦听网络适配器时,我需要使用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
.
.
.
Run Code Online (Sandbox Code Playgroud)
执行时的进程列表:
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$
Run Code Online (Sandbox Code Playgroud)
如上所示,执行后,PID = 4685 和 PID = 4686 的进程添加到进程列表中。为什么?我没有在里面调用我的程序!
hee*_*ayl 12
当你这样做时:
sudo ./lwdpi -i enp5s0
Run Code Online (Sandbox Code Playgroud)
sudo是父进程,它fork(2)SA的孩子,然后做execve(2)与./lwdpi作为可执行文件名
的子进程lwdpi也是如此sudo
如您所见,这会导致两个过程,一个是sudo,另一个是lwdpi。
查看详细信息的最佳方法是也检查 PPID(父进程 ID):
ps -eo pid,ppid,args | grep '[l]wdpi'
Run Code Online (Sandbox Code Playgroud)
你会看到它lwdpi的父母是sudo它自己。
这是sudo的流程模型,来自man sudo:
当sudo运行一个命令时,它会调用fork(2),如上所述设置执行环境,并在子进程中调用execve系统调用。主 sudo 进程等待命令完成,然后将命令的退出状态传递给安全策略的关闭函数并退出。
如果配置了 I/O 日志插件或安全策略明确请求它,则会创建一个新的伪终端(“pty”),并使用第二个 sudo 进程在用户现有的 pty 和新的 pty 之间中继作业控制信号pty 命令正在运行。这个额外的过程使得暂停和恢复命令成为可能。没有它,该命令将处于 POSIX 术语中的“孤立进程组”,并且不会接收任何作业控制信号。
作为一种特殊情况,如果策略插件没有定义关闭函数并且不需要 pty,则 sudo 将直接执行命令而不是先调用 fork(2)。sudoers 策略插件将仅在启用 I/O 日志记录、需要 pty 或启用 pam_session 或 pam_setcred 选项时定义关闭功能。请注意,在使用 PAM 的系统上默认启用 pam_session 和 pam_setcred。
当您使用 启动任何进程时会发生这种情况sudo一个进程是sudo程序,另一个是使用 启动的程序sudo,它是第一个进程的子进程。在sudo当进程正在运行的(其子)退出程序只能退出。这是我pstree跑步时的摘录sudo apt update
??mate-terminal??
??bash???sudo???apt
child of bash--^ ^--child of sudo
Run Code Online (Sandbox Code Playgroud)