簡體   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

我有一個運行 python 腳本的批處理文件,在 python 腳本中,我有一個正在運行的子進程函數。

我嘗試過subprocess.check_outputsubprocess.runsubprocess.Popen ,只有在使用批處理文件運行它時,它們才會返回一個空字符串。

如果我手動或使用 IDE 運行它,我會得到正確的響應。 下面是subprocess.run的代碼:

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

響應在 stdout=b''

在批處理文件和任務計划程序中運行時:

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

手動或在 IDE 中運行時:

命令響應:CompletedProcess(args='tableau refreshextract --config-file "Z:\\XXX\\tableau_config\\SampleSuperStore.txt"', returncode=0, stdout=b'數據源刷新完成。\\r\\n0 行已上傳。\\ r\\n', stderr=b'')

運行python程序的批處理文件。 參數被解析到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%"

這是為什么??

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

包裝類:

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

自動化類:

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 文件導致了這個問題,但看起來它在手動運行批處理文件時有效,但在任務計划程序上設置時無效

更新

首先,如果需要通過調用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()
  • 上面代碼的結果將是一個運行anaconda-prompt實例

現在問題看起來像:


我有一個運行 python 腳本batch file ,在 python 腳本中,我有一個正在運行的subprocess函數。

我已按要求實施了相同的程序; 假設我們有

  • 批處理文件---> 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運行批處理文件后的結果。

使用運行子流程方法的 Task Schedular 輸出給定的批處理文件。

發生這種情況是因為您的 ide 沒有在以打開子進程期望的方式工作的 shell 中運行。

如果您設置 SHELL=False 並指定批處理文件的絕對路徑,它將運行。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM