如何使用 "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 的状态。
我正在尝试 运行 使用 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 的状态。