Subprocess 运行, check_output, Popen returns 空字符串当我 运行 来自批处理文件和任务计划程序的脚本时

Subprocess run, check_output, Popen returns empty string when I run the script from a batch file and from Task Scheduler

我有一个批处理文件,它是 运行 一个 python 脚本,在 python 脚本中,我有一个子进程函数,它是 运行。

我试过 subprocess.check_outputsubprocess.runsubprocess.Popen,所有这些 returns 只有在使用批处理 运行 时才给我一个空字符串文件。

如果我 运行 手动或使用 IDE,我会得到正确的响应。下面是 subprocess.run:

的代码
    response = subprocess.run(fileCommand, shell=True, cwd=pSetTableauExeDirectory, capture_output=True)
    self.writeInLog(' Command Response: \t' + str(response))

响应在 stdout=b''

当 运行 在批处理文件和任务计划程序中时:

Command Response: CompletedProcess(args='tableau refreshextract --config-file "Z:\XXX\tableau_config\SampleSuperStore.txt"', returncode=0, stdout=b'', stderr=b'')

当运行手动或在IDE时:

Command Response: CompletedProcess(args='tableau refreshextract --config-file "Z:\XXX\tableau_config\SampleSuperStore.txt"', returncode=0, stdout=b'Data source refresh completed.\r\n0 rows uploaded.\r\n', stderr=b'')

运行python 程序的批处理文件。参数解析为python application

SET config=SampleSuperStore.txt
CALL C:\XXX\AppData\Local\Continuum\anaconda3\Scripts\activate.bat
C:\XXX\AppData\Local\Continuum\anaconda3\python.exe Z:\XXX\pMainManual.py "%config%"

这是为什么?

--完成python代码---

try:
    from pWrapper import wrapper
    import sys
except Exception as e:
    print(str(e))

class main:

    def __init__(self):
        self.tableauPath = 'C:\Program Files\Tableau\Tableau 2018.3\bin\'
        self.tableauCommand = 'tableau refreshextract --config-file' 

    def runJob(self,argv): 
        self.manual_sProcess(argv[1])

    def manual_sProcess(self,tableauConfigFile):    
        new_wrapper = wrapper()
        new_wrapper.tableauSetup(self.tableauPath,self.tableauCommand)
        if new_wrapper.tableauConfigExists(tableauConfigFile):
            new_wrapper.tableauCommand(tableauConfigFile)           

if __name__ == "__main__":
    new_main = main()
    new_main.runJob(sys.argv)  

包装器class:

def tableauCommand(self,tableauConfigFile):    
    command = self.setTableauExeDirectory + ' ' + self.refreshConfigCommand + ' "' + tableauConfigFile + '"'
    self.new_automateTableauExtract.runCommand(tableauConfigFile,command,self.refreshConfigCommand,self.tableauFilePath,self.setTableauExeDirectory)   

自动化 Class:

def runCommand(self,pConfig,pCommand,pRefreshConfigCommand,pFilePath,pSetTableauExeDirectory):
    try:
        fileCommand = pRefreshConfigCommand + ' "' + pFilePath + '"'
        response = subprocess.run(fileCommand, shell=True, cwd=pSetTableauExeDirectory, capture_output=True)
        self.writeInLog(' Command Response: \t' + str(response))
    except Exception as e:
        self.writeInLog('Exception in function runCommand: ' + str(e))

更新:我最初认为是 bat 文件导致了这个问题,但看起来它在 运行 手动批处理文件时有效,但在任务计划程序

上设置时无效

已更新

首先,如果需要运行 anaconda-prompt通过调用activate.bat文件,可以简单的如下操作:

import subprocess


def call_anaconda_venv():
    subprocess.call('python -m venv virtual.env')
    subprocess.call('cmd.exe /k /path/venv/Scripts/activate.bat')


if __name__ == "__main__":
    call_anaconda_venv()
  • 上述代码的结果将是 运行ning 实例 of anaconda-prompt 根据需要。

现在问题好像是:


I have a batch file which is running a python script and in the python script, I have a subprocess function which is being run.

我已经按要求实现了相同的程序;假设我们有

  • 批处理文件 ---> script.bat **** 包含一个 命令 运行 python 脚本即 test.py。 ****

  • Python 脚本文件 ---> test.py **** 包含一个 方法 到 运行 命令使用 subprocess。 ****

  • 批处理文件 ---> sys_info.bat **** 包含一个 命令提供我电脑的系统信息。 ****


现在,script.bat 包含一个命令,该命令将 运行 所需的 python 脚本如下所示;

python \file_path\test.py 
pause

这里,pause命令用于防止执行后自动关闭控制台。现在我们有 test.py、python 脚本,其中包括 subprocess 方法到 运行 所需的命令并获得它们的 输出


from subprocess import check_output


class BatchCommands:

    @staticmethod
    def run_commands_using_subprocess(commands):
        print("Running commands from File: {}".format(commands))
        value = check_output(commands, shell=True).decode()

        return value

    @staticmethod
    def run():
        commands_from_file = "\file-path\sys_info.bat"

        print('##############################################################')
        print("Shell Commands using >>> subprocess-module  <<<")
        print('##############################################################')

        values = BatchCommands.run_commands_using_subprocess(commands_from_file)
        print(values)


if __name__ == '__main__':
    BatchCommands.run()

现在,最后,我有一个 sys_info.bat 文件,其中包含更新计算机 IP 地址的命令。 sys_info.bat文件中命令如下;

systeminfo

sys_info.bat 文件中放置多个命令,然后您也可以一次 运行 多个命令,例如:

ipconfig/all
ipconfig/release
ipconfig/reset
ipconfig/renew
ipconfig

在使用该文件之前,将所有文件 directory paths 和 运行 批处理文件即 command-prompt 中的 script.py 设置如下;

  • 运行 命令提示符或终端作为 administrator.

     run \file_path\script.py
    

这是在 terminal.

中 运行 处理批处理文件后的结果

发生这种情况是因为您的 ide 未 运行 在 shell 中以打开子进程期望的方式工作。

如果您设置 SHELL=False 并指定批处理文件的绝对路径,它将 运行。

如果批处理文件需要,您可能仍然需要 cwd。