Недостаточно информации, чтобы ответить на этот вопрос окончательно, но я могу сделать некоторые обоснованные предположения.
Во-первых, os.remove
определенно не должно быть неудачным с EPIPE.Это тоже не похоже;ошибка close failed: [Errno 32] Broken pipe
, а не remove failed
.Похоже, что close
терпит неудачу, а не remove
.
Возможно закрытие stdout канала, чтобы выдать эту ошибку.Если данные буферизуются, Python сбросит данные перед закрытием файла.Если базовый процесс исчез, выполнение этого вызовет IOError / EPIPE.Однако обратите внимание, что это не фатальная ошибка: даже когда это происходит, файл все еще закрыт .Следующий код воспроизводит это примерно в 50% случаев и демонстрирует, что файл закрывается после исключения.(Остерегайтесь; я думаю, что поведение bufsize изменилось в разных версиях.)
import os, subprocess
metadataPipes = subprocess.Popen("echo test", stdin=subprocess.PIPE,
stdout=subprocess.PIPE, shell=True, close_fds=True, bufsize=4096)
metadataPipes.stdin.write("blah"*1000)
print metadataPipes.stdin
try:
metadataPipes.stdin.close()
except IOError, e:
print "stdin after failure: %s" % metadataPipes.stdin
Это неестественно;это происходит только часть времени.Это может объяснить, почему это выглядело как удаление или добавление вызова os.remove
влияет на ошибку.
Тем не менее, я не могу понять, как это произойдет с предоставленным вами кодом, поскольку вы этого не делаетенапиши в stdin.Это самое близкое, что я могу получить без полезного репродукции, и, возможно, оно укажет вам правильное направление.
В качестве примечания, вы не должны проверять os.path.exists перед удалением файла.это может не существовать;это вызовет состояние гонки, если другой процесс одновременно удалит файл.Вместо этого сделайте следующее:
try:
os.remove(inFileAsGzip)
except OSError, e:
if e.errno != errno.ENOENT: raise
... которую я обычно заключаю в такую функцию, как rm_f
.
Наконец, если вы явно хотите уничтожить подпроцесс, есть metadataPipes.kill
- просто закрытие его каналов не сделает этого - но это не поможет объяснить ошибку.Кроме того, опять же, если вы просто читаете файлы gzip, вам гораздо лучше использовать модуль gzip, чем подпроцесс.http://docs.python.org/library/gzip.html