简体   繁体   English

当我从批处理文件和任务计划程序运行脚本时,子进程运行、check_output、Popen 返回空字符串

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

I have a batch file which is running a python script and in the python script, I have a subprocess function which is being ran.我有一个运行 python 脚本的批处理文件,在 python 脚本中,我有一个正在运行的子进程函数。

I have tried subprocess.check_output , subprocess.run , subprocess.Popen , all of them returns me an empty string only when running it using a batch file.我尝试过subprocess.check_outputsubprocess.runsubprocess.Popen ,只有在使用批处理文件运行它时,它们才会返回一个空字符串。

If I run it manually or using an IDE, I get the response correctly.如果我手动或使用 IDE 运行它,我会得到正确的响应。 Below is the code for subprocess.run :下面是subprocess.run的代码:

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

Response is in stdout=b''响应在 stdout=b''

When ran in batch file and from task scheduler:在批处理文件和任务计划程序中运行时:

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

When ran manually or in IDE:手动或在 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'')命令响应:CompletedProcess(args='tableau refreshextract --config-file "Z:\\XXX\\tableau_config\\SampleSuperStore.txt"', returncode=0, stdout=b'数据源刷新完成。\\r\\n0 行已上传。\\ r\\n', stderr=b'')

Batch file which runs the python program.运行python程序的批处理文件。 Parameters are parsed to the python application参数被解析到python应用程序

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%"

Why is that??这是为什么??

--Complete python code--- --完整的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)  

Wrapper class:包装类:

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

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

UPDATE: I initially thought that the bat file was causing this issue but it looks like it works when running manually a batch file but not when it is set on task scheduler更新:我最初认为是 bat 文件导致了这个问题,但看起来它在手动运行批处理文件时有效,但在任务计划程序上设置时无效

Updated更新

First of all, if there is a need to run anaconda-prompt by calling activate.bat file, you can simply do as follows:首先,如果需要通过调用activate.bat文件来运行anaconda-prompt ,可以简单的进行如下操作:

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()
  • The result of the above code would be a running instance of anaconda-prompt as required.上面代码的结果将是一个运行anaconda-prompt实例

Now as Problem Seems Like:现在问题看起来像:


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.我有一个运行 python 脚本batch file ,在 python 脚本中,我有一个正在运行的subprocess函数。

I have implemented the same program as required;我已按要求实施了相同的程序; Suppose we have假设我们有

  • Batch File ---> script.bat **** includes a command to run python script ie test.py .批处理文件---> script.bat **** 包括一个运行 python 脚本的命令,即test.py **** ****

  • Python Script File ---> test.py **** includes a method to run commands using subprocess . Python脚本文件---> test.py ****包括使用运行命令的方法subprocess **** ****

  • Batch File ---> sys_info.bat **** includes a command which would give the system information of my computer.批处理文件---> sys_info.bat **** 包含一个命令,该命令将提供我的计算机的系统信息。 **** ****


Now First, script.bat includes a command that will run the required python script as given below;现在首先, script.bat包含一个命令,该命令将运行所需的 python 脚本,如下所示;

python \file_path\test.py 
pause

Here, pause command is used to prevent auto-closing console after execution.在这里, pause命令用于防止在执行后自动关闭控制台。 Now we have test.py , python script which includes subprocess method to run required commands and get their output .现在我们有了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()

Now, in the end, I have a sys_info.bat file which includes commands to renew the IP-Adress of my computer.现在,最后,我有一个sys_info.bat文件,其中包含更新计算机 IP 地址的命令。 Commands in sys_info.bat file are as follows; sys_info.bat文件中的命令如下;

systeminfo

Place multiple commands in sys_info.bat file, then you can also run multiple commands at a time like:将多个命令放在sys_info.bat文件中,然后您也可以一次运行多个命令,例如:

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

Before to use the file, set all files directory paths , and run the batch file ie script.py in command-prompt as follows;在使用该文件之前,设置所有文件的directory paths ,并在command-prompt运行批处理文件即script.py ,如下所示;

  • Run command-prompt or terminal as an administrator .administrator身份运行命令提示符或终端。

     run \\file_path\\script.py

Here is the result after running the batch file in the terminal .这是在terminal运行批处理文件后的结果。

使用运行子流程方法的 Task Schedular 输出给定的批处理文件。

This is happening because your ide is not running in a shell that works in the way that open subprocess is expecting.发生这种情况是因为您的 ide 没有在以打开子进程期望的方式工作的 shell 中运行。

If you set SHELL=False and specify the absolute path to the batch file it will run.如果您设置 SHELL=False 并指定批处理文件的绝对路径,它将运行。

you might still need the cwd if the batch file requires it.如果批处理文件需要,您可能仍然需要 cwd。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM