繁体   English   中英

如何使用“子进程”运行复杂的批处理命令

[英]How to run complicated batch command using “subprocess”

我试图使用子进程模块运行批处理命令,但它只是无法正常工作。 这是我的代码:

import subprocess
subprocess.Popen('for /l %i in (5,1,255) do start /B ping -w 1 -n 1 192.168.0.%i | find /i "Reply"', stdout=subprocess.PIPE)
while True:
    line = p.stdout.readline()
    if not line:
        print 'DONE PING'
        break
    print line

但每次运行此代码时,我都会收到“WindowsError:[错误2]系统无法找到指定的文件”。
如何使用子进程模块运行此批处理命令?

由于'for'是一个cmd命令,而不是一个可执行文件,除了设置shell = True参数之外你可以添加cmd / C或cmd / K取决于你想要发生什么,请参阅'cmd /?':

C:\Users\equinox93>cmd /?
Starts a new instance of the Windows command interpreter

CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
[[/S] [/C | /K] string]

/C      Carries out the command specified by string and then terminates
/K      Carries out the command specified by string but remains
/S      Modifies the treatment of string after /C or /K (see below)
/Q      Turns echo off
/D      Disable execution of AutoRun commands from registry (see below)
/A      Causes the output of internal commands to a pipe or file to be ANSI
/U      Causes the output of internal commands to a pipe or file to be
    Unicode
/T:fg   Sets the foreground/background colors (see COLOR /? for more info)
/E:ON   Enable command extensions (see below)
/E:OFF  Disable command extensions (see below)
/F:ON   Enable file and directory name completion characters (see below)
/F:OFF  Disable file and directory name completion characters (see below)
/V:ON   Enable delayed environment variable expansion using ! as the
    delimiter. For example, /V:ON would allow !var! to expand the
    variable var at execution time.  The var syntax expands variables
    at input time, which is quite a different thing when inside of a FOR
    loop.
/V:OFF  Disable delayed environment expansion.

因此,例如在您的情况下,修复可能是:

subprocess.Popen('cmd /C for /l %i in (5,1,255) do start /B ping -w 1 -n 1 192.168.0.%i | find /i "Reply"', stdout=subprocess.PIPE)

您需要设置参数shell=True以便它允许您运行cmd命令( for不是程序)

这将有效:

subprocess.Popen('for /l %i in (5,1,255) do start /B ping -w 1 -n 1 192.168.0.%i | find /i "Reply"', stdout=subprocess.PIPE,  shell=True)

编辑:

当您运行的命令使用用户输入时,不建议使用Shell=True 从你的问题来看,似乎不是你的情况。 无论如何,如果你想确定,你可以将命令保存到bat文件中并使用subprocess.Popen运行它。

所以你有了:

subprocess.Popen('mycommand.bat', stdout=subprocess.PIPE) 

在我的command.bat文件中你写道:

for /l %i in (5,1,255) do start /B ping -w 1 -n 1 192.168.0.%i | find /i "Reply"

你可以在python中进行循环并分别调用每个ping。 您还可以测试每个ping的退出值,而不是搜索其输出。

import subprocess
import shlex

def do_ping(address):
    cmd = "ping -w 1 -n 1 {}".format(address)
    # ping exits with 0 on success, or 1-255 otherwise
    return not subprocess.call(shlex.split(cmd))

def job():
    for i in range(5, 256):
        result = do_ping("192.168.0.{}".format(i))
        if result:
            print("successful ping")
            break
    else:
        print("ping failed")

或者你可以在python中完成整个程序。 通过使用ping模块(不是标准库的一部分)。 您需要修改Ping.do以返回真实值,而不是打印ping的状态。

暂无
暂无

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

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