Подтвердить что ты не робот

Трубопроводы и степеды

Я хочу вызвать скрипты из каталога (они исполняемые скрипты оболочки) через 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 script с функцией startt. из которого я звоню

эхо "Что-то"

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

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

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

4b9b3361

Ответ 1

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

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

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

Popen.returncode: код возврата ребенка, установленный poll() и wait() (и косвенно посредством communication()).

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

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 не является правильным, если вы не обрабатываете конкретное исключение. Вместо 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