简体   繁体   中英

Why can't timeout take effect for tcpdump run under sudo?

I want to run the tcpdump command with a time limit of 10 seconds.

timeout 10 sudo tcpdump -i eth0 -nn 'host 192.168.1.176'

It doesn't stop. Why does the timeout command not take effect for tcpdump here?

The problem is that timeout runs with your users privileges. The sudo process escalates privileges to root (or another user), so timeout is not allowed to send SIGTERM to the child process. This can be shown with strace (comments starting with # by me, as well as blank lines for readability):

user$ strace timeout 1 sudo sleep 5
# lots of irrelevant stuff
# here, timeout sets up the timer to get a signal when the child should be terminated
rt_sigprocmask(SIG_UNBLOCK, [ALRM], NULL, 8) = 0
timer_create(CLOCK_REALTIME, {sigev_value={sival_int=1889673072, sival_ptr=0x560c70a21f70}, sigev_signo=SIGALRM, sigev_notify=SIGEV_SIGNAL}, [0]) = 0
timer_settime(0, 0, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=1, tv_nsec=0}}, NULL) = 0
wait4(12320, 0x7ffdfeb0ef0c, 0, NULL)   = ? ERESTARTSYS (To be restarted if SA_RESTART is set)

# the signal arrives
--- SIGALRM {si_signo=SIGALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=1889673072, ptr=0x560c70a21f70}} ---

# timeout tries to kill the child
kill(12320, SIGTERM)                    = -1 EPERM (Operation not permitted)
# and gets EPERM!

The fix is to run timeout with root privileges also. The following will work as intended:

user$ sudo timeout 1 sleep 5

Of course, if you already are root, it doesn't matter whether you put timeout 1 before or after the sudo in the command line.

root$ sudo timeout 1 sleep 5
root$ timeout 1 sudo sleep 5

试试这个:

sudo timeout 10 tcpdump -i eth0 -nn 'host 192.168.1.176'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM