2017-09-01 75 views
0

我在樹莓派上運行一個Plex服務器,並且遇到了讓庫更新的問題,所以我正在編寫一個可以調用來更新所有或特定的Python類庫。從命令管道運行在不同的用戶下Popen python3

我想使它儘可能一般,即使用庫名稱而不是庫號碼,但我遇到了一些問題。 「Plex Media Scanner」命令必須在我當前設置的Plex用戶帳戶下運行。我可以使用下面的代碼運行命令(在sudo下運行),但我無法捕獲該命令的輸出,即代碼的Popen部分運行時,庫的列表會打印到終端,但是, check_output命令不會返回任何內容。我已經嘗試將stdout和stderr都管道到subprocess.PIPE,但那些也不捕獲任何東西。

運行下面的代碼給我下面的輸出

15: Fitness 
10: Movies 
    8: Music 
    2: TV Shows 
b'' 

與前四行是POPEN的輸出和check_output的最後輸出。我已經使用簡單的['ls','-l']命令進行了測試,其他所有設置都相同,check_output可以捕獲輸出。這告訴我它必須只是Plex命令。有沒有人有類似的問題來捕獲命令的輸出,如果是的話,你是如何解決它的?

#!/usr/bin/env python3 
import subprocess as subp; 
import pwd, os; 

class plex_scan(): 
    def __init__(self): 
     self.pw_record = pwd.getpwnam('plex'); 
     self.env = os.environ.copy() 
     self.env['HOME'   ] = self.pw_record.pw_dir 
     self.env['PWD'   ] = self.pw_record.pw_dir 
     self.env['LOGNAME'  ] = self.pw_record.pw_name 
     self.env['USER'   ] = self.pw_record.pw_name 
     self.env['PYTHONHOME'  ] = "/usr/lib/plexmediaserver/Resources/Python"; 
     self.env['LD_LIBRARY_PATH'] = "${LD_LIBRARY_PATH}:/usr/lib/plexmediaserver"; 

     cmd = ['/usr/lib/plexmediaserver/Plex Media Scanner', '--list'] 
     self.proc = subp.Popen(cmd, env=self.env); 
     self.proc.wait(); 
     out = subp.check_output(cmd, env=self.env); 
     print(out); 
if __name__ == "__main__": 
    x = plex_scan(); 
    exit(0); 

回答

1

終於想出瞭解決這個問題的辦法。問題在於Plex Media Scanner程序正在寫入4kb緩衝區和子進程.PIPE沒有捕捉到它。

我加

stdbuf -oL -eL 

到命令的乞討被運行,使得新的命令

cmd = ['stdbuf', '-oL', '-eL', '/usr/lib/plexmediaserver/Plex Media Scanner', '--list'] 

,這並獲得成功。另請參見:

https://www.reddit.com/r/learnpython/comments/1dmhsz/subprocesspopen_stdout_flush_the_buffer/#bottom-comments

https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe