Вопрос по python – Трубопроводы попен стдерр и стдоут
Я хочу вызывать скрипты из каталога (они являются исполняемыми скриптами оболочки) через 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 (), но мой не работает так, как я думал.
Что я делаю неправильно?
Любая помощь высоко ценится
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