У меня есть старый скрипт на python 2.7.5, который неожиданно создает проблемы в Red Hat Enterprise Linux Server версии 7.6 (Maipo). В конце концов, я вижу, что он отлично работает на Red Hat Enterprise Linux Server версии 7.4 (Maipo). Сценарий в основном реализует что-то вроде
cat /proc/cpuinfo | grep -m 1 -i 'cpu MHz'
путем создания двух подпроцессов и передачи вывода первого во второй (см. Пример кода ниже). В более новой версии ОС процессы cat остаются открытыми до тех пор, пока скрипт не завершится.
Кажется, что канал к grep каким-то образом удерживает процесс cat открытым, и я не могу найти никакой документации о том, как явно закрытьit.
Проблему можно воспроизвести, вставив этот код в CLI Python, а затем проверив список процессов ps на наличие статического процесса cat / proc / cpuinfo. Код разбивает то, что изначально происходит внутри цикла, поэтому, пожалуйста, не спорьте о его стиле. ; -)
import shlex
from subprocess import *
cmd1 = "cat /proc/cpuinfo"
cmd2 = "grep -m 1 -i 'cpu MHz'"
args1 = shlex.split(cmd1) # split into args
args2 = shlex.split(cmd2) # split into args
# first process uses default stdin
ps1 = Popen(args1, stdout=PIPE)
# then use the output of the previous process as stdin
ps2 = Popen(args2, stdin=ps1.stdout, stdout=PIPE)
out, err = ps2.communicate()
print(out)
После этого проверьте список процессов во втором сеансе (!) С помощью:
ps -eF |grep -v grep|grep /proc/cpuinfo
В RHEL7.4 я не обнаружил открытого процессав списке процессов, тогда как в RHEL 7.6 после некоторых попыток это выглядит следующим образом:
[reinski@myhost ~]$ ps -eF |grep -v grep|grep /proc/cpuinfo
reinski 2422 89459 0 26993 356 142 18:46 pts/3 00:00:00 cat /proc/cpuinfo
reinski 2597 139605 0 26993 352 31 18:39 pts/3 00:00:00 cat /proc/cpuinfo
reinski 7809 139605 0 26993 352 86 18:03 pts/3 00:00:00 cat /proc/cpuinfo
Эти процессы исчезнут только после закрытия CLI Python, и в этом случае я получаю такие ошибки (я оставилформатирование испорчено, как было):
cat: write error: Broken pipe
cat: write errorcat: write error: Broken pipe
: Broken pipe
Почему cat, очевидно, все еще хочет писать в канал, даже если он должен был уже вывести весь файл / proc / cpuinfo и должен был завершиться сам?
Или более важно: как я могу предотвратить это?
Спасибо за любую помощь!
Пример 2:
Учитывая предложение VPfB, оноОказалось, что мой пример был немного неудачным, поскольку ожидаемый результат может быть достигнут с помощью одной команды grep. Итак, вот модифицированный пример, чтобы показать проблему с конвейером по-другому:
import shlex
from subprocess import *
cmd1 = "grep -m 1 -i 'cpu MHz' /proc/cpuinfo"
cmd2 = "awk '{print $4}'"
args1 = shlex.split(cmd1) # split into args
args2 = shlex.split(cmd2) # split into args
# first process uses default stdin
ps1 = Popen(args1, stdout=PIPE)
# then use the output of the previous process as stdin
ps2 = Popen(args2, stdin=ps1.stdout, stdout=PIPE)
out, err = ps2.communicate()
print(out)
На этот раз результатом является один процесс-зомби для процесса grep (169731 - pid сеанса python):
[reinski@myhost ~]$ ps -eF|grep 169731
reinski 169731 189499 0 37847 6024 198 17:51 pts/2 00:00:00 python
reinski 193999 169731 0 0 0 142 17:53 pts/2 00:00:00 [grep] <defunct>
Итак, это просто еще один признак той же проблемы, или я здесь что-то не так делаю?