如何使用 "subprocess" 运行 复杂的批处理命令

How to run complicated batch command using "subprocess"

我正在尝试 运行 使用 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: [Error 2] The system cannot find the file specified"。
我如何 运行 使用 subprocess 模块执行此批处理命令?

您需要设置参数 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"

因为'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)

您可以在 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 修改为 return 真实值,而不是打印 ping 的状态。