繁体   English   中英

嵌套for循环,设置变量以及是否在批处理脚本中

[英]nested for loop, set variable and if else in a batch script

我正在尝试制作一个批处理脚本,该脚本将在文件中写入特定的IP地址。 我有一个txt文件(由一个python脚本创建),具有一个IP地址列表(每个换行中一个),现在我需要使用for循环ping通这些IP,检查TTL值是否在100到128之间(Windows主机)并将IP地址写入新文件。 我一直试图调整以设置变量和for循环,但这一切都变得太复杂而无法运行。
到目前为止,我已经达到:-
编辑:在命令下方更正

for /f %i in (ip.txt) do ping -n 1 %i | find "TTL"

这将给我多行Ping输出,此处仅显示单行(例如,我使用的是4.2.2.2)

Reply from 4.2.2.2: bytes=32 time=1 ms ttl=45

如果我对单个IP执行ping操作,则可以选择TTL字段,但不能选择TTL的确切值

for /f "tokens=6 delims= " %a in ('ping -n 1 4.2.2.2 ^| find "TTL"') do echo %a

它给我的值为TTL=45而我需要45进行比较。 我读到了有用的setlocal enabledelayedexpansion ,但我无法将它们全部合并成一行,无法使用set变量和IF-ELSE循环。
请简要介绍如何实现IP选择。

制作批处理脚本解决方案后,由我编辑:
此批处理脚本将ping ips.txt文件中给定的每个IP地址。 查找TTL值,如果TTL值等于128,它将运行命令NBTSTAT -A ip-address (用于查找GROUP信息)并将其存储在nbt_query_op.txt文件中。
在为每个IP地址触发NBTSTAT命令之前,将在该文件中搜索现有结果,如果在文件中未找到特定IP的结果,则将触发NBTSTAT。
请注意变量应以括起来引用 字符!TTL! ,!ip1! !!错误级别! 此外,还要感谢RGuggisberg先生提供的指导。

@echo off
setlocal EnableDelayedExpansion
for /f %%i in (ips.txt) do (
for /f "tokens=6 delims= " %%a in ('ping -n 1 %%i ^| find "TTL"') do (
    for /f "tokens=2 delims==" %%b in ('echo.%%a') do set ttl=%%b
    echo %%i has TTL:- !ttl!
    if !TTL! == 128      (set ip1=%%i
                 echo        SELECTED IP- !ip1! TTL- !TTL!
                 findstr /c:!ip1! nbt_query_op.txt
                 if not !ERRORLEVEL! ==0 echo !ip1!>>nbt_query_op.txt && nbtstat -A !ip1! | find "GROUP">>nbt_query_op.txt
                     )
                                          )
)


谢谢,
克里斯

这将满足您的要求。 迁移到第一个示例时,根据需要进行修改。

for /f "tokens=6 delims= " %a in ('ping -n 1 4.2.2.2 ^| find "TTL"') do for /f "tokens=2 delims==" %b in ('echo.%a') do echo %b

顺便说一句,您帖子中的第一个FOR循环不完整。 我想你是说

for /f %i in (ip.txt) do ping -n 1 %i | find "TTL"

在vbscript中,您可以执行以下操作:

strHost = "4.2.2.2"
if Ping(strHost) = True then
    Wscript.Echo "Host " & strHost & " contacted"
Else
    Wscript.Echo "Host " & strHost & " could not be contacted"
end if
'***************************************************************************************
Function Ping(strHost)
    dim objPing, objRetStatus
    set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
      ("select * from Win32_PingStatus where address = '" & strHost & "'")
    for each objRetStatus in objPing
        if IsNull(objRetStatus.StatusCode) or objRetStatus.StatusCode <> 0 then
            Ping = False
            WScript.Echo "Status code is " & objRetStatus.StatusCode
        else
            Ping = True
            Msg = Msg & " Pingging " & strHost & vbCrlf & vbCrlf 
            Msg = Msg & "Bytes = " & objRetStatus.BufferSize & vbCrlf 
            Msg = Msg & "Time (ms) = " & objRetStatus.ResponseTime & vbCrlf 
            Msg = Msg & "TTL (s) = "  & objRetStatus.ResponseTimeToLive 
        end if
    next
    Wscript.echo Msg
End Function 
'***************************************************************************************

编辑:30/06/2016 @ 19:11

我测试了这个文件:file.txt

 4.2.2.2 www.google.com www.google.fr www.facebook.com www.stackoverflow.com www.yahoo.com www.yahoo.fr www.developpez.net 

这个批处理文件:

@echo off
Title Get TTL from IP adress
set vbsfile=%Tmp%\%~n0.vbs
set IP_File=E:\vb-ping\ip.txt
set LogFile=Log.txt
If Exist %LogFile% Del %LogFile%
For /f %%a in ('Type %IP_File%') Do ( 
    echo TTL for "%%a" is : & Call:VBS "%%a"
    ( echo TTL for "%%a" is : & Call:VBS "%%a" )>> %LogFile%
)
echo.
color 0A
echo Hit any key to open the LogFile "%LogFile%"
pause>nul
Start "" %LogFile%
Exit /b

:VBS 
(
    echo wscript.echo TTL(WScript.Arguments(0^)^)
    echo '**********************************************************************************************************
    echo Function TTL(strHost^)
    echo     dim objPing, objRetStatus
    echo     set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}"^).ExecQuery _
    echo       ("select * from Win32_PingStatus where address = '" ^& strHost ^& "'"^)
    echo     for each objRetStatus in objPing
    echo         if IsNull(objRetStatus.StatusCode^) or objRetStatus.StatusCode ^<^> 0 then
    echo            Ping = False
    echo           WScript.Echo "Status code is " ^& objRetStatus.StatusCode
    echo        else
    echo            Ping = True
    echo            TTL = objRetStatus.ResponseTimeToLive 
    echo        end if
    echo     next
    echo End Function 
    echo '**********************************************************************************************************
)> "%vbsfile%"
Cscript /Nologo "%vbsfile%" "%~1"
Exit /b

我得到的输出结果是这样的:

 TTL for "4.2.2.2" is : 53 TTL for "www.google.com" is : 51 TTL for "www.google.fr" is : 51 TTL for "www.facebook.com" is : 81 TTL for "www.stackoverflow.com" is : 53 TTL for "www.yahoo.com" is : 48 TTL for "www.yahoo.fr" is : 48 TTL for "www.developpez.net" is : 48 

因此,我的答案似乎与我寻求的答案有所不同。 它在python 2.x中,我刚写完。 尽管它不是很复杂并且在执行方面很隐蔽(弹出许多CMD窗口并写入文件,然后读取以形成结果)。 但是仍然完成了工作。 我想我将不得不对DOS命令进行更多研究并开始学习VB脚本;)。 大声笑。
谢谢@RGuggisberg和@Hackoo的支持

import os
import re
cwd = os.getcwd()
ip_file = cwd+"\\ip.txt"     ## IPs written in this file, one in each line, or the filename can be taken through command-line args (more portable)
ip = []
win_hosts = []
for line in open(ip_file).readlines():
    ip.append(line.rstrip())
del_cmd = "del "+cwd+"\\response.txt"    ## Delete response.txt file
os.system(del_cmd)                       ## as PING output keeps appending to it
for i in ip:
    cmd = "ping -n 1 "+str(i)+' | find "TTL" >> response.txt'    ## write PING response to response.txt
    os.system(cmd)
response_file = cwd+"\\response.txt"
for line in open(response_file).readlines():
    regs = r'Reply from\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*TTL=(\d{1,3})'   ## Regular Expression to catch IP and TTL-value
    obj = re.search(regs,line.rstrip('\n'))  ## also right-strip any possible new-lines, it'll probably be '\r\n' on Linux host
    if obj:
        ip = obj.group(1)
        ttl = obj.group(2)
        print ip," has TTL= ",ttl
        ttl = int(ttl)
        if (127<ttl<129):                ## change this to (54<ttl<65) to get Linux hosts
            win_hosts.append(ip)         ## Add the windows hosts to win_hosts list
print "\n[+][+] Windows Hosts = ",str(win_hosts)

我的ip.txt文件具有:-

192.168.1.1
192.168.1.2
192.168.1.4
192.168.1.5

其结果是:-

>>> 
192.168.1.1  has TTL=  30
192.168.1.2  has TTL=  64
192.168.1.4  has TTL=  64
192.168.1.5  has TTL=  128

[+][+] Windows Hosts =  ['192.168.1.5']

我不完全记得,但是无法获得命令模块 (在Windows上不支持)和子进程模块尽管它们在Linux机器上可以正常工作 )的支持。 如果有人对如何将结果存储到任何列表/字典/变量有任何想法,请更新。 我不喜欢在CMD中使用输出重定向。

尝试此批处理文件以在具有IP地址的同一行中获取TTL

@echo off
Title Get TTL from IP adress
set vbsfile=%Tmp%\%~n0.vbs
set IP_File=E:\vb-ping\ip.txt
set LogFile=Log.txt
If Exist %LogFile% Del %LogFile%
For /f %%a in ('Type %IP_File%') Do ( 
     Call:VBS "%%a" & echo  %%a
    ( Call:VBS "%%a" & echo  %%a)>> %LogFile%
)
echo.
color 0A
echo Hit any key to open the LogFile "%LogFile%"
pause>nul
Start "" %LogFile%
Exit /b

:VBS 
(
    echo WScript.StdOut.Write TTL(WScript.Arguments(0^)^)
    echo '**********************************************************************************************************
    echo Function TTL(strHost^)
    echo     dim objPing, objRetStatus
    echo     set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}"^).ExecQuery _
    echo       ("select * from Win32_PingStatus where address = '" ^& strHost ^& "'"^)
    echo     for each objRetStatus in objPing
    echo         if IsNull(objRetStatus.StatusCode^) or objRetStatus.StatusCode ^<^> 0 then
    echo            Ping = False
    echo           WScript.Echo "Status code is " ^& objRetStatus.StatusCode
    echo        else
    echo            Ping = True
    echo            TTL = objRetStatus.ResponseTimeToLive 
    echo        end if
    echo     next
    echo End Function 
    echo '**********************************************************************************************************
)> "%vbsfile%"
Cscript /Nologo "%vbsfile%" "%~1"
Exit /b

因此,我为所有Windows客户端(不是Org的域的一部分)创建了完整的扫描脚本。 时间已经足够长了,但我想在这里发布。

该脚本依赖于使用nmap的 ping-sweep进行的初始客户端扫描。 由于使用多重处理模块创建脚本无法在Windows Box上运行,因此最好的镜头是nmap NMAP在几秒钟内对255个主机的完整子网进行ping扫描,并返回在网络中发现的客户端的FQDN(完全限定域名)。

注意:您应该拥有在扫描仪PC中定义的DNS服务器。

脚本要做的下一件事是,将nmap扫描的输出/ item到文件nmap_op.txt中 然后脚本从该文件读取输出,并使用正则表达式取出IP和FQDN。 如果任何IP没有FQDN,则对其执行ping操作一次,然后将输出写入到文件response.txt中 读取该文件,并取出TTL值在100-129之间的IP。

add_to_db函数负责返回实际上不属于域的IP列表。 此功能对具有3个列表的IP进行交叉检查,并将IP从数据库文件中的最终列表中删除,但后来又加入了Domain,并且在它们联机时也不断向DB添加新的非域IP。

将此python文件保存在脚本可以写入文件的目录中。 您应该查找两个文件non-domain-ips.txt (所有非域IP)和[subnet_value] -result.txt以获取最终结果。

用法 -在命令提示符下运行此文件,如下所示:
python scan.py 192.168.1.0/24 192.168.2.0/24
您可以添加任意数量的网络进行扫描。 请不要更改网络arg的模式。 您只能使用“ /”来定义网络的掩码值(不要使用*代替/)。 传递的参数没有异常处理。 运行脚本时将理解其余的输出。

此外,我正在考虑添加一个或两个以上功能,以根据其MAC地址的供应商位将某些IP定义为例外。 例如,某些瘦客户机类型的设备(因为它们将仅在独立模式下运行),它们提供了Windows范围的TTL值。
脚本是匆忙编写的,没有使用任何类(而且我不太喜欢它们),所以它的形式最丑陋;)

import os
import time
import re
import sys
import pickle
import commands
import subprocess

def add_to_db(nondomain_ips, pickled_ips, domainIPs):
    print "NON domain IPs= ", str(nondomain_ips)
    #raw_input("....")
    print "PICKLED IPs= ",str(pickled_ips)
    #raw_input("....")
    print "Length of PICKLED IPs= ",len(pickled_ips)
    print "domain IPs:- ",str(domainIPs)
    #raw_input("....")
    if (len(pickled_ips) == 0):
        pickled_ips= nondomain_ips
        return pickled_ips
    for new_ip in nondomain_ips:
        print "comparing- ",str(new_ip)
        if new_ip not in pickled_ips:
            print "APPENDING ",str(new_ip),"  to PICKLED IPs"
            pickled_ips.append(new_ip)           
        else:   pass
    for pickled_ip in pickled_ips:
        #print "CHECKING - ",pickled_ip," in domain and in DB file or not"
        if pickled_ip in domainIPs:
            print pickled_ip," JOINED domain, removing from DB file"
            pickled_ips.remove(pickled_ip)
    #print "PICKLED IPs:- ",str(pickled_ips)
    #raw_input("...")
    return pickled_ips
def main():
    if (len(sys.argv)<2):
        print "Wrong args, Give the subnet to scan, Example- \n\npython script.py 192.168.1.0/24 192.168.2.0/24 [more subnets...]\n\nExiting...\n"
        exit(3)
    print "TOTAL SUBNETS TO SCAN:- ",len(sys.argv)
    cwd = os.getcwd()
    print "Current Directory= ",cwd
    outfile = cwd+"\\nmap_op.txt"
    for i in range(1,len(sys.argv)):
    time_now = time.ctime()
        net = sys.argv[i]
        #print i
        #cmd = "nmap -sn " + str(sys.argv[i]) + " -oG "+str(outfile)
        cmd = "nmap -sn " + str(net) + " -oG "+str(outfile)
        print cmd
        try:
            os.remove(outfile)
        except Exception, e:
            print "Error deleting file",str(e)
        #raw_input("SENDING -sn SCAN....\n")
        print "SENDING -sn SCAN....\n"
        os.system(cmd)

        #print "Argv[i]= ",sys.argv[i].split('/')[0]
        print "Argv[i]= ",net.split('/')[0]
        result_file = str(cwd)+"\\"+net.split('/')[0]+"-result.txt"
        print "result file= ",result_file
        #raw_input(" ... ")
        if os.path.exists(outfile):
            print outfile," - oG file created\n\n-------------------------------------\n"
        fp = open(outfile)
        hostlist=[]
        domainIPs = []
        nondomain = []
        ping_file = cwd+"\\response.txt"
        try:
            os.remove(ping_file)
        except Exception, e:
            e=e
        for line in fp.readlines():
            #print line
            #reg = r'Host:(.*\)).*Status.*Up'
            reg = r'Host:\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s(\(.*\)).*Status.*Up'
            res = re.match(reg,line)
            if res:
                #print "\t\t",res.group()
                ip = res.group(1)
                if ('()' in res.group(2)):
                    name = 0
                    nondomain.append([ip,name])
                    ping_cmd = 'ping -n 1 '+str(ip)+'| find "TTL" >>'+cwd+"\\response.txt"
                    os.system(ping_cmd)
                else:
                    name = res.group(2)
                    domainIPs.append(ip)
                hostlist.append([ip,name])
            else:   pass #print "No object"
        fp.close()      ## CLOSE THE NMAP OUTPUT FILE-HANDLE
        print "[+][+] All HOSTS:- ",str(hostlist),"\n"
        #print "domain IPs:- ",str(domainIPs)
        print "TOTAL unresolved IPs:- ",nondomain,"\n"
        nondomain_ip = []
        #print "\n\nIP and TTL from RegExp\n"
        regs = r'Reply from\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*TTL=(\d{1,3})'
        for line in open(ping_file).readlines():
            #print line
            obj = re.search(regs,line)
            if obj:
                ip = obj.group(1)
                ttl = obj.group(2)
                print str(ip)+" --- " + str(ttl)
                if (100<int(ttl)<129):
                    nondomain_ip.append(ip)
        #print "non domain IPs = ",str(nondomain_ip)
        fp_result = open(result_file,'a')
        fp_result.write("\n\n"+time_now+"\n")
        fp_result.write(str(nondomain_ip))
        fp_result.close()

        db_file = cwd+"\\dbfile"
        if not os.path.exists(db_file):
            fpdb = open(db_file,'w')
            fpdb.close()
            if os.path.exists(db_file):
                print "DB_FILE created"
        with open(db_file,'rb') as fpdb:
            try:
                pickled_ips = pickle.load(fpdb)
            except Exception, error:
                print "Error in loading pickeled list"
                pickled_ips = []
                print "Formed new pickled list= ",str(pickled_ips)
        fpdb.close()
        new_list = add_to_db(nondomain_ip, pickled_ips, domainIPs)
        #print "\nNEW IP-ADDRESSES ESTABLISHED AFTER COMPARING ALL LISTS:- \n",str(new_list)
        with open(db_file, 'wb') as fpdb:
            pickle.dump(new_list, fpdb)
        fpdb.close()
        with open(db_file, 'rb') as fpdb:
            ips = pickle.load(fpdb)
            print "\n\n\t\tTHE NON-domain IPs:- \n",str(ips)
            with open("non-domain-ips.txt",'wb') as handle:
                for ip in ips:
                    handle.write(ip)
                    handle.write("\r\n")
            handle.close()
        print "SLEEPING FOR 10 SECONDS..."
        time.sleep(10)
if __name__ == '__main__':
    while True:
        main()
        print "\n\n\n\t\tSCAN COMPLETED...sleep for 5 minutes before running another loop of scan...\n\n\n"
        time.sleep(300)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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