Если ваше ядро поддерживает контроллер памяти cgroup v1 и он включен (, насколько мне известно, он включен во всех основных дистрибутивах Linux ), вы сможете использовать значение root memory.max_usage_in_bytes
для этого:
echo "$(("$(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes)" / 2**20)) MB"
Why is the occurrenceBrokenPipeError dependent on the size of what is being piped?
Потому что для написания большего количества материала требуется больше времени, и правая часть конвейера может умереть до того, как ваш питон закончит ее писать. Кроме того, если python попытается записать больше, чем помещается в буфер канала, он заблокируется и даст head -1
достаточно времени для выхода.
Поскольку head -1
требуется некоторое время, чтобы жить и умирать, python может использовать это время для записи всего своего материала --, если он помещается в буфер конвейера --и успешно завершает работу. Это трудно предсказать, поскольку ядро может планировать обе стороны конвейера в любом порядке и может откладывать запуск head -1
до тех пор, пока считает нужным, или может остановить его в любое время.
>>> python3 -c 'for i in range(50000): print("")' | sleep.01
Traceback (most recent call last):
File "<string>", line 1, in <module>
BrokenPipeError: [Errno 32] Broken pipe
>>> python3 -c 'for i in range(50000): print("")' | sleep.1
# OK!
Но если python попытается написать больше материала, чем умещается в конвейере, он неизбежно получит EPIPE
или SIGPIPE
в конце, независимо от того, сколько времени у него есть:
>>> python3 -c 'for i in range(100000): print("")' | sleep 20
Traceback (most recent call last):
File "<string>", line 1, in <module>
BrokenPipeError: [Errno 32] Broken pipe
but that is 64K for me... so that doesn't seem to be the reason.
Имейте в виду, что python использует полную буферизацию , когда вывод не является терминалом; он пишет не построчно или байт за байтом, а кусками некоторого размера:
>>> strace -s3 -e trace=write python3 -c 'for i in range(50000): print("")' | sleep.3
write(1, "\n\n\n"..., 8193) = 8193
write(1, "\n\n\n"..., 8193) = 8193
write(1, "\n\n\n"..., 8193) = 8193
write(1, "\n\n\n"..., 8193) = 8193
write(1, "\n\n\n"..., 8193) = 8193
write(1, "\n\n\n"..., 8193) = 8193
write(1, "\n\n\n"..., 842) = 842
+++ exited with 0 +++