Python subprocess.call()显然不能与psexec一起使用

时间:2014-08-21 19:17:22

标签: python subprocess psexec

我在使用subprocess.call()和psexec执行远程进程时遇到问题。我使用以下语法通过subprocess.call()远程执行进程:

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

为什么这不起作用的任何想法?如果重要,则通过两个或3个主机列表上的多处理map()函数调用执行函数。

任何帮助都会很棒!谢谢!

1 个答案:

答案 0 :(得分:2)

主机名前面的\\双斜线只是一个斜杠;为了逃避斜线,它增加了一倍。

您可以在shlex.split()输出中看到这一点:

['psexec', '\\HOSTNAME', '-e, '-s', '-d', '-w', 'c:\\', 'c:\\script.exe']

请注意,主机名之前的\\只是两个反斜杠,就像c:\\文件名值一样。。如果只打印该值,则会看到sart上的反斜杠只是一个字符:

>>> 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)