В каком-то смысле делать это в Python - это слегка безумие, когда это намного проще сделать лаконично в сценарии оболочки. Но вот go при рефакторинге вашего кода.
Обычно вам следует избегать subprocess.Popen()
, если можете; ваш код был бы проще и понятнее c с subprocess.run()
. Но в этом случае, когда find
потенциально может возвращать много совпадений, мы можем захотеть обработать файлы так, как они сообщаются, вместо того, чтобы ждать, пока подпроцесс завершит sh, а затем собрать его вывод. Используя код из этого ответа на переполнение стека и адаптируясь в соответствии с Фактическое значение 'shell = True' в подпроцессе , чтобы избежать shell=True
, попробуйте что-то вроде
#!/usr/bin/env python3
from subprocess import Popen, PIPE
import gzip
from tempfile import NamedTemporaryFile
import shutil
import os
with Popen(
['find' '/var/log', '--name=syslog*', '-mtime', '+' + specific_delete_range],
stdout=PIPE, bufsize=1, text=True) as p:
for filename in p.stdout:
filename = filename.rstrip('\n')
temp = NamedTemporaryFile(delete=False)
with gzip.open(filename, 'rb') as f, gzip.open(temp, 'wb') as z:
for line in f:
if my_str_as_bytes not in line:
z.write(line)
os.unlink(filename)
shutil.copy(temp, filename)
os.unlink(temp)
С text=True
нам не нужно decode
вывод из Popen
. Строки из gzip
по-прежнему являются двоичными байтами; мы могли бы, конечно, их декодировать, но вместо этого кодирование строки поиска в байты, как вы это сделали, более эффективно.
Суть в том, что мы используем временный файл для отфильтрованного результата, а затем перемещаем его обратно поверх исходного файла, как только мы его закончим.
NamedTemporaryFile
имеет некоторые печальные особенности на Windows, но, к счастью для вас, вы не на Windows.