我正在尝试限制在我用来嗅探内部网络以审核网络中的Linux服务器的脚本中生成的子shell数量。该脚本按预期工作,但由于我嵌套for
循环的方式,它为每个网络生成255个子shell,因此它会因为有超过1000个进程产生而导致CPU死亡。我需要能够限制进程数量,并且由于变量在Sub Shell中失去了它们的价值,我无法找到一种方法来使其工作。再次,脚本工作,它只产生了一个进程 - 我需要限制它,比如说最多10个进程:
#!/bin/bash
FILE=/root/ats_net_final
for network in `cat $FILE`;do
for ip in $network.{1..255};do
(
SYSNAME=`snmpwalk -v2c -c public -t1 -r1 $ip sysName.0 2>/dev/null | awk '{ print $NF }'`
SYSTYPE=`snmpwalk -v2c -c public -t1 -r1 $ip sysDescr.0 2>/dev/null | grep -o Linux`
if [ $? -eq 0 ];then
echo "$SYSNAME"
exit 0;
else
echo "Processed $ip"
exit 0
fi
) &
done
done
This解决方案我发现它有效,但不是我的情况,因为无论如何,它仍然会在限制进程的逻辑之前产生进程。我想也许我只是在看代码太久了,这只是一个简单的逻辑问题而且我把东西放在错误的区域,或者顺序错误。
我接受了huitseeker的回答。他能够为我提供逻辑运作方向,让我能够使用它。最后的剧本:
#!/bin/bash
FILE=/root/ats_net_final
for network in `cat $FILE`;do
#for ip in $network.{1..255};do
for ip in {1..255};do
(
ip=$network.$ip
SYSNAME=`snmpwalk -v2c -c public -t1 -r1 $ip sysName.0 2>/dev/null | awk '{ print $NF }'`
SYSTYPE=`snmpwalk -v2c -c public -t1 -r1 $ip sysDescr.0 2>/dev/null | grep -o Linux`
if [ $? -eq 0 ];then
echo "$SYSNAME"
exit 0;
else
echo "Processed $ip"
exit 0
fi
) &
if (( $ip % 10 == 0 )); then wait; fi
done
wait
done
答案 0 :(得分:2)
将并发子单元数限制为10的简单方法是:
for ip in $(seq 1 255);do
(<whatever you did with $ip in the subshell here, do with $network.$ip instead >) &
if (( $ip % 10 == 0 )); then wait; fi
done
wait
最后一次等待是有用的,不要让内环的最后一轮的子壳与下一轮外圈的第一轮中创建的子壳重叠。
答案 1 :(得分:1)
我想我找到了更好的解决方案。我使用make实现了
#!/usr/bin/make -f
IPFILE := ipfile
IPS:=$(foreach ip,$(shell cat $(IPFILE)),$(foreach sub,$(shell seq 1 1 254),$(ip).$(sub)))
all: $(IPS)
$(IPS):
SYSNAME=`snmpwalk -v2c -c public -t1 -r1 $@ sysName.0 2>/dev/null | awk '{ print $$NF }'`; \
SYSTYPE=`snmpwalk -v2c -c public -t1 -r1 $@ sysDescr.0 2>/dev/null | grep -o Linux`; \
if [ $$? -eq 0 ]; then \
echo "$$SYSNAME"; \
else \
echo "Processed $@"; \
fi
IP的第一部分(例如192.168.1)应放在ipfile中。然后它将所有IP地址生成到变量IPS
中(如192.168.1.1 ... 192.168.1.254 ...)。
这些行可以复制到例如test.mak
并为文件添加执行权限。如果将其作为./test.mak
运行,则它将逐个处理IPS
中的IP。但如果它以./test.mak -j 10
运行,那么它将同时处理10个IP。它也可以./test.mak -j 10 -l 0.5
运行。它将运行最多10个进程或直到系统负载达到0.5。