2012-05-21 17 views
16

Chcę wywołać skrypty z katalogu (są to wykonywalne skrypty powłoki) za pośrednictwem Pythona.Rury popen stderr i stdout

tej pory tak dobrze:

for script in sorted(os.listdir(initdir), reverse=reverse): 
     if script.endswith('.*~') or script == 'README': 
      continue 
     if os.access(script, os.X_OK): 
      try: 
       execute = os.path.abspath(script) 
       sp.Popen((execute, 'stop' if reverse else 'start'), 
         stdin=None, stderr=sp.PIPE, 
         stdout=sp.stderr, shell=True).communicate() 
      except: 
       raise 

Teraz to, co chcę jest: powiedzmy, że mam skryptu bash z functiont startu. z którego nazywam

echo „coś”

Teraz chcę zobaczyć, że Echo dnia sys.stdout a kod wyjścia. Wierzę, że robisz to z .communicate(), ale moje nie działa tak jak myślałem.

Co robię źle?

Każda pomoc jest mile widziane

Odpowiedz

49

konsultacyjne http://docs.python.org/library/subprocess.html.

communicate() zwraca krotkę (stdoutdata, stderrdata).

Po podproces zakończył, można uzyskać kod zwrotny od instancji POPEN:

Popen.returncode: Kod powrotu dziecka, ustawione przez poll() i czekaj() (i pośrednio przez komunikację()).

Podobnie, można osiągnąć swoje cele tak:

sp = subprocess.Popen([executable, arg1, arg2], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = sp.communicate() 
if out: 
    print "standard output of subprocess:" 
    print out 
if err: 
    print "standard error of subprocess:" 
    print err 
print "returncode of subprocess:" 
print sp.returncode 

Nawiasem mówiąc, chciałbym zmienić test

if script.endswith('.*~') or script == 'README': 
     continue 

w pozytywny:

if not filename.endswith(".sh"): 
    continue 

Lepiej wypowiadać się na temat tego, co chciałbyś zrobić bardziej ekscytować niż być jednoznacznym o tym, co robisz nie chcesz wykonać.

Powinieneś także nazwać zmienne w bardziej ogólny sposób, więc script powinno być w pierwszej kolejności filename. Ponieważ listdir zawiera również listę katalogów, można je jawnie sprawdzić. Twój bieżący blok try/except nie jest prawidłowy, o ile nie obsługuje określonego wyjątku. Zamiast abspath powinieneś po prostu połączyć initdir i filename, co jest pojęciem często stosowanym w kontekście os.listdir(). Ze względów bezpieczeństwa, używaj shell=True w konstruktorze obiektu Popen tylko wtedy, gdy masz absolutną pewność, że go potrzebujesz. Pozwolę sobie zasugerować, co następuje:

for filename in sorted(os.listdir(initdir), reverse=reverse): 
    if os.path.isdir(filename) or not filename.endswith(".sh"): 
     continue 
    if os.access(script, os.X_OK): 
     exepath = os.path.join(initdir, filename) 
     sp = subprocess.Popen(
      (exepath, 'stop' if reverse else 'start'), 
      stderr=subprocess.PIPE, 
      stdout=subprocess.PIPE) 
     out, err = sp.communicate() 
     print out, err, sp.returncode 
+0

Dziękuję bardzo –

+0

Tak, mam szczególne wyjątki po prostu nie wpisać je w thy ponieważ nie są istotne pytania. Ale masz rację co do nazw zmiennych, zawsze zmagam się z własnymi imionami, więc dziękuję jeszcze raz –

Powiązane problemy