2017-09-01 9 views
0

私はラズベリーパイのPlexサーバーを実行しています。ライブラリを更新する際に問題が発生しましたので、すべてまたは特定のものを更新するために呼び出すことができるPythonクラスを作成しましたライブラリ。パイプを別のユーザーの下で実行するPopen python3

ライブラリ番号の代わりにライブラリ名を使用してできるだけ一般化したいと考えていますが、いくつかの問題が発生しています。 「Plex Media Scanner」コマンドは、現在の設定でPlexユーザーアカウントで実行する必要があります。次のコード(sudoの下で実行)を使用して実行するコマンドを取得できますが、コードのPopen部分が実行されたときにライブラリのリストが端末に出力されたときに、 check_outputコマンドは何も返しません。私はsubprocess.PIPEにstdoutとstderrの両方を配管しようとしましたが、それらは何も取得しません。以下のコードを実行

は私の最初の4行はcheck_outputの出力popenの出力と最後であることと、次の出力

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

を与えます。私は単純な['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

最後に、この問題を解決しました。問題は、プレックス・メディア・スキャナー・プログラムが4kbバッファーとサブプロセスに書き込んでいることでした.PIPEはそれを捕まえていませんでした。

私は新しいコマンドに

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

を作り、実行するコマンドの物乞いに

stdbuf -oL -eL 

を追加し、これはトリックをしました。参照:

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

関連する問題