我正在尝试使用子进程模块运行批处理命令但它只是不起作用。 这是我的代码:
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]系统无法找到指定的文件”。
如何使用子进程模块运行此批处理命令?
答案 0 :(得分:2)
因为'for'是cmd命令,而不是可执行文件, 除了设置shell = True param你可以添加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)
答案 1 :(得分:1)
您需要设置参数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"
答案 2 :(得分:0)
您可以在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的状态。