Python subprocess.call() 与 psexec 似乎无法配合使用
我在用 subprocess.call()
和 psexec 执行远程进程时遇到了一些问题。我使用以下语法来远程执行进程:
def execute(hosts):
''' Using psexec, execute the script on the list of hosts '''
successes = []
wd = r'c:\\'
file = r'c:\\script.exe'
for host in hosts:
res = subprocess.call(shlex.split(r'psexec \\%s -e -s -d -w %s %s ' % (host,wd,file)), stdin=None, stdout=None, stderr=None)
if res == 0:
successes.append(host)
else:
logging.warning("Error executing script on host %s with error code %d" % (host, res))
print shlex.split(r'psexec \\%s -e -s -d -w %s %s ' % (hosts[0],wd,file))
return successes
正如你所看到的,作为故障排除的一部分,我打印了 shlex.split()
的输出,以确保它是我想要的。这条打印语句的输出是:
['psexec', '\\HOSTNAME', '-e', '-s', '-d', '-w', 'c:\\', 'c:\\script.exe']
这正是我所期待的。不幸的是,当我运行它时,出现了一个错误,提示:
PsExec could not start \GN-WRK-02:
The system cannot find the file specified.
紧接着,我用程序应该用的确切语法运行 psexec 命令(根据 shlex.split()
的输出判断),结果完全正常。我的语法是:
psexec \\HOSTNAME -e -s -d -w c:\\ c:\\script.exe
有没有人知道为什么这不工作?如果有帮助的话,执行函数是通过 multiprocessing 的 map()
函数在两个或三个主机列表上调用的。
任何帮助都非常感谢!谢谢!
1 个回答
2
你在主机名前面的 \\
双斜杠其实只算一个斜杠;它是重复的,用来表示转义这个斜杠。
你可以在 shlex.split()
的输出中看到这一点:
['psexec', '\\HOSTNAME', '-e, '-s', '-d', '-w', 'c:\\', 'c:\\script.exe']
注意,在主机名之前的 \\
其实就是两个反斜杠,就像在 c:\\
文件名中一样。 如果你只打印这个值,你会发现开头的反斜杠其实只是一个字符:
>>> print '\\HOSTNAME'
\HOSTNAME
>>> '\\HOSTNAME'[0]
'\\'
>>> '\\HOSTNAME'[1]
'H'
这是因为 shlex.split()
是一个 POSIX 工具,而不是 Windows 工具,它也把原始字符串中的 \\
视为转义;如果你在使用这个工具,就需要再把斜杠加倍:
shlex.split(r'psexec \\\\%s -e -s -d -w %s %s ' % (host,wd,file))
另一种选择可能是 禁用 POSIX 模式,但我不太确定这在 Windows 上会有什么影响:
shlex.split(r'psexec \\%s -e -s -d -w %s %s ' % (host,wd,file), posix=False)