[英]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.