Вопрос по python – Трубопроводы попен стдерр и стдоут

21

Я хочу вызывать скрипты из каталога (они являются исполняемыми скриптами оболочки) через python.

Все идет нормально:

    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

Теперь то, что я хочу: допустим, у меня есть bash-скрипт с функцией start. из которого я звоню

echo "Something"

Теперь я хочу увидеть это эхо на sys.stdout и код выхода. Я полагаю, что вы делаете это с .communicate (), но мой не работает так, как я думал.

Что я делаю неправильно?

Любая помощь высоко ценится

Ваш Ответ

1   ответ
57

http: //docs.python.org/library/subprocess.htm.

communicate () возвращает кортеж (stdoutdata, stderrdata).

После завершения подпроцесса вы можете получить код возврата из экземпляра Popen:

Popen.returncode: дочерний код возврата, установленный poll () и wait () (и косвенно - connect ()).

Кроме того, вы можете достичь своих целей следующим образом:

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

Кстати, я бы поменял тест

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

в позитив:

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

Лучше быть явно о том, что вы хотели бы выполнить, чем о том, что вы делаетен хочу исполнить.

Кроме того, вы должны называть свои переменные в более общем виде, поэтомуscript должно бытьfilename в первую очередь. Какlistdir также перечисляет каталоги, вы можете явно проверить их. Ваш текущийtry/except block не является правильным, если вы не обрабатываете конкретное исключение. Вместо тогоabspath, тебе просто нужно объединитьinitdir а такжеfilename, которая часто применяется в контекстеos.listdir(). В целях безопасности используйтеshell=True в конструктореPopen возражать, только если вы абсолютно уверены, что вам это нужно. Позвольте мне предложить следующее:

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
Да, у меня есть конкретные исключения, я их просто не напечатал, потому что они не имеют отношения к вопросу. Но вы правы относительно имен переменных, я всегда борюсь с собственными именами, поэтому еще раз спасибо wagner-felix

Похожие вопросы