2017-09-01 53 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

相关问题