我想在我自己的脚本中启动 tcpdump,一段时间后我想再次杀死它。如何从 tcpdump 访问 PID?我用 $$ 尝试过,但这只会杀死脚本。
if [[ $TIMEEND != $Zeit ]];then
echo "tcpdump started"
sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
pid1=$!
break
#sudo umount /dev/sdb1
else
sudo kill $pid1
echo "autodump stopped"
fi
这是我 grep tcpdump 时的输出,所以我认为不可能使用 pidof 和 pkill。
我尝试用 awk 来做
pid1=$(ps -eo pid,args|awk '/abfrage2/ && ! /awk/{print $1}')
echo $pid1 >> /tmp/test.txt
sudo kill $pid1
当我直接使用 pid 命令时,它会找到 pid 但不会执行 kill。
我想我必须稍微考虑一下我的代码。我从配置文件中导入时间,然后检查开始时间是否相同,如果是,还应该检查它是否不是结束时间。然后,只要不是结束时间,它就应该执行 tcpdump。当它到达结束时间时,它应该杀死 tcpdump。我知道这不是最好的解决方案,但如果能让它与类似的东西一起工作那就太好了。
#!/bin/sh
source /media/usbhd-sdb1/config.conf
pluggedin=true
echo $TIMESTART
echo $TIMEEND
echo $$
echo $Zeit
echo $$ >> /tmp/test.txt
while [ $pluggedin ];do
Zeit=$(date +"%T")
if [[ $TIMESTART == $Zeit ]];then
if [[ $TIMEEND != $Zeit ]];then
echo "tcpdump started"
sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
#sudo umount /dev/sdb1
else
pid1=$(ps -eo pid,args|awk '/abfrage2/ && ! /awk/{print $1}')
echo $pid1 >> /tmp/test.txt
sudo kill -9 $pid1
echo "autodump stopped"
fi
else
echo "tcpdump not yet started"
fi
done
答案1
如果我理解你想运行 tcpdump 一段时间并杀死它。您可以执行以下操作:
#!/bin/bash
sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
PID=$!
sleep 20
sudo kill -9 $PID
exit 0
将为$!
您提供启动命令的 pid。要杀死它,您可以调用kill [Signal] [PID]
杀死 tcpdump 命令。
请注意,我们运行 tcpdump背景在&
命令末尾添加 ,否则 tcpdump 将继续执行前景。这exit 0
将确保脚本在最后被杀死。
[概念证明]
bash -x a.sh
+ PID=21988
+ sleep 10
+ tcpdump -i eth0 -w abfrage2.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
+ kill -9 21988
+ exit 0
[或者]
正如埃里克所建议的,你也可以这样做暂停命令
#!/bin/bash
timeout 10s tcpdump -i eth0 -w abfrage2.pcap
exit 0
答案2
您的命令应该通过在该行sudo tcpdump
附加一个 & 符号来进入后台:&
sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
该行pid1=$!
会将命令的 PID 放入sudo tcpdump
变量中pid1
如果你想终止该进程,你应该使用:
sudo kill $pid1
您使用$$
它代表当前正在运行的进程的PID。
由于您在另一个脚本中使用它,您可能会多次调用该脚本,因此所有后续运行都没有使用的pid1
变量。
要获取此变量中的 PID,您可以使用:
pid1=$(pidof tcpdump)
在else
你的脚本部分。
或者直接使用:
sudo pkill tcpdump
假设您只运行一份 tcpdump 副本。
您需要注意的另一件事。每次您调用脚本并且$TIMEEND
不等于$Zeit
它时,都会启动另一个tcpdump
进程。更好的解决方案是:
if [ "$TIMEEND" != "$Zeit" ] && [ "$(pidof tcpdump)" == "" ]
这将测试时间要求和tcpdump
流程的存在性。
答案3
同一脚本的不同调用之间不会保留变量值。这意味着,您无法将程序 PID 保存在变量中,并期望在再次运行脚本时将该变量初始化为该值。
将 PID 值保存在临时文件中:
if [...] ; then
sudo tcpdump -i eth0 ..... &
disown
echo $! > somefile.pid
echo "started"
else
cat somefile.pid | xargs -n 1 kill
echo "stopped"
fi
注意这个命令保存的sudo
是PID,而不是tcpdump
pid,这意味着你不需要sudo
再次杀死它
另外,如果您希望后台命令比执行脚本的 shell 持续时间更长,您应该disown
在启动后立即执行