Shell异步,pid的获取
问题:
程序A是个死循环的Ddos攻击软件,每次退出时用Ctrl+C太麻烦了,现在想写个Shell脚本来设定时间
方案一:
1 #!/bin/bash 2 echo "'''IcmpFlood'''" 3 DstIp="10.24.8.85" 4 DstPort="80" 5 echo "DstIp:$DstIp" 6 echo "DstPort:$DstPort" 7 echo "Time:10s" 8 sudo ./icmp -d $DstIp -p $DstPort 9 sleep 10 10 kill $! //打印当前pid $$;打印最后进入后台进程的pid $!
发现Shell在第8行卡住了,它是顺序执行的,没有达到要求;
方案二:
1 #!/bin/bash 2 echo "'''IcmpFlood'''" 3 DstIp="10.24.8.85" 4 DstPort="80" 5 echo "DstIp:$DstIp" 6 echo "DstPort:$DstPort" 7 echo "Time:10s" 8 sudo ./icmp -d $DstIp -p $DstPort& //command&代表这条命令后台执行 9 sleep 10 10 kill $!
达到要求,在command后面加&,使其在后台运行,前台等10s后,杀死后台进程;
方案三:
1 #!/bin/bash 2 echo "'''IcmpFlood'''" 3 DstIp="10.24.8.85" 4 DstPort="80" 5 echo "DstIp:$DstIp" 6 echo "DstPort:$DstPort" 7 echo "Time:10s" 8 sudo ./icmp -d $DstIp -p $DstPort& 9 sleep 10 10 kill `pgrep icmp` //获取icmp的进程号
为什么会有第三种方案?
使用$!虽然很方便,但是在多线程中没有加锁的情况下,$!并不一定是你想得到的pid,所以我使用了pgrep来获取icmp的pid,保险....
还有,为了保证pgrep得到的pid唯一,最好将程序名起得长一点,确定它不会重复,My_Icmp_Flood之类的....
总结:
command&: 让命令后台运行;
$$: 获取当前进程pid;
$!: 获取最后进入后台进程pid;
jobs: 获取后台进程信息,并终端显示;
[1]+ 运行中 sudo ./icmp -d $DstIp -p $DstPort &
kill %1 即可
下面是网上的:
- ps -A |grep "cmdname"| awk '{print $1}'
- pidof "cmdname"
- pgrep "cmdname"
这三种在bash和busybox ash里面的运行结果稍有不同,
第一种完全相同,但是因为调用命令次数较多,性能上是不行的。
第二种: pidof 只能获取程序的文件名匹配到的进程号,在ash中 比如 pidof "usr/bin/telnetd" 和 pidof "telnetd"中结果不一样, 前一种结果为空,但是在bash中执行两者一样。
第三种: pgrep跟1的效果相同,因为是单一命令,比第一种性能要好得多。
所以nanoRC就改进为pgrep。