从命令管道运行在不同的用户下Popen python3
问题描述:
我在树莓派上运行一个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);
答
终于想出了解决这个问题的办法。问题在于Plex Media Scanner程序正在写入4kb缓冲区和子进程.PIPE没有捕捉到它。
我加
stdbuf -oL -eL
到命令的乞讨被运行,使得新的命令
cmd = ['stdbuf', '-oL', '-eL', '/usr/lib/plexmediaserver/Plex Media Scanner', '--list']
,这并获得成功。另请参见:
https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe