более длинная строка для tr вызывает зависание и всплеск процессора

MacOS Yosemite (10.10.5). Я знаю, что это раздел Unix / Linux … но этот вопрос, вероятно, подходит лучше, чем в MacOS.

Мой терминал начал зависать при запуске, прежде чем показывать подсказку … и одновременное использование процессора. Я могу CTRL-C, а затем получить подсказку (предположительно выходящую из висячего / работающего .bashrc / .profile / etc).

Я быстро понял, что некоторые строки в моем .bashrc вызывают зависание. Это новое (т. Е. Я ничего не менял в своем .bashrc, и все было хорошо работает), поэтому что-то изменилось в системе.

Кажется, что некоторые более длинные строки приводят к всплеску зависания / процессора.

Я могу воспроизвести это, передав строку в tr -d '\n' и увидев, если она зависает.

 macattack:~ $ openssl rand -base64 93 | tr -d '\n' eDsz4JqFX/HAVjplNI6WDWwPRp9l9snp6UKp/pLn+GbBvJx0+ZMvSJFS/SuCwjMRRXVXfUvBdkaH1R0UgCr2UOf283MvHVTRusLFEVPcGCIz1t3sFMU/3foRzNWVmattp@macattack:~ $ openssl rand -base64 94 | tr -d '\n' ^C mattp@macattack:~ $ openssl rand -base64 94 | tr -du '\n' ^C 

Кажется, что 93 символа – это магическое число, где tr начинает зависать. openssl не висит (т. е. если я удаляю трубку до tr все выйдет). Однако моя оригинальная проблемная линия оказалась разной длины.

 mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log;' | tr -d '\n' ^C-bash: echo: write error: Interrupted system call mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | tr -d '\n' mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | wc -c 128 mattp@macattack:~ $ 

Вероятно, это проблема с трубкой, а не проблема tr . Я могу воспроизвести ту же проблему с sed (команда не имеет смысла … просто иллюстрирует зависание).

 mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log;' | sed 's/\n/ /g' ^C-bash: echo: write error: Interrupted system call mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | sed 's/\n/ /g' echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log mattp@macattack:~ 

У меня не хватало идей для устранения этой проблемы.
Команды подвески выполняются нормально на случайном сервере linux centos. До недавнего времени команды выполнялись отлично на macos. Раньше я никогда не сталкивался с трубкой. Я подумал, может быть, это были странные символы ввода, вызывающие проблему … но случайная строка openssl показывает иначе. Улимиты такие же, как на другом маке, у которого нет этой же проблемы.

 mattp@macattack:~ $ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 7168 pipe size (512 bytes, -p) 1 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 709 virtual memory (kbytes, -v) unlimited 

Используя dtruss on tr похоже, он зависает на вызове read_nocancel.

Обновить

Продвигается. Нашел комментарий о размерах висячих и трубных буферов. Снял тестовый скрипт отсюда: насколько большой буфер для буфера?

Запуск, пока происходит проблема, показывает буфер буфера 128 байтов. Перезагрузка (проблема временно уходит), а буфер канала – 65536 байт. См. Тестовый результат ниже.

Итак, теперь возникает вопрос: почему / как «что-то» уменьшает размер буфера в системе.

С проблемой

 $ /bin/bash -c 'for p in {0..18}; do pipe-buffer-test.sh $((2 ** $p)) 0.5; done' write size: 1; bytes successfully before error: 128 write size: 2; bytes successfully before error: 128 write size: 4; bytes successfully before error: 128 write size: 8; bytes successfully before error: 128 write size: 16; bytes successfully before error: 128 write size: 32; bytes successfully before error: 128 write size: 64; bytes successfully before error: 128 write size: 128; bytes successfully before error: 128 write size: 256; bytes successfully before error: 0 write size: 512; bytes successfully before error: 0 write size: 1024; bytes successfully before error: 0 write size: 2048; bytes successfully before error: 0 write size: 4096; bytes successfully before error: 0 write size: 8192; bytes successfully before error: 0 write size: 16384; bytes successfully before error: 0 write size: 32768; bytes successfully before error: 0 write size: 65536; bytes successfully before error: 0 write size: 131072; bytes successfully before error: 0 write size: 262144; bytes successfully before error: 0 

После перезагрузки (проблема временно исчезла)

 $ /bin/bash -c 'for p in {0..18}; do pipe-buffer-test.sh $((2 ** $p)) 0.5; done' write size: 1; bytes successfully before error: 65536 write size: 2; bytes successfully before error: 65536 write size: 4; bytes successfully before error: 65536 write size: 8; bytes successfully before error: 65536 write size: 16; bytes successfully before error: 65536 write size: 32; bytes successfully before error: 65536 write size: 64; bytes successfully before error: 65536 write size: 128; bytes successfully before error: 65536 write size: 256; bytes successfully before error: 65536 write size: 512; bytes successfully before error: 65536 write size: 1024; bytes successfully before error: 65536 write size: 2048; bytes successfully before error: 65536 write size: 4096; bytes successfully before error: 65536 write size: 8192; bytes successfully before error: 65536 write size: 16384; bytes successfully before error: 65536 write size: 32768; bytes successfully before error: 65536 write size: 65536; bytes successfully before error: 65536 write size: 131072; bytes successfully before error: 0 write size: 262144; bytes successfully before error: 0 

  • Процесс был убит из-за низкого обмена
  • OS X Postfix не найден TLS
  • Кросс-компиляция статического библиотеки ARM с GCC для Mac iOS xCode
  • Объясните пользователю Linux, как работают драйверы BSD / OSX
  • Почему мой Mac, обновленный от Mavericks до Yosemite, больше не предоставляет ресурсам VMware Fusion?
  • эта команда работает, но когда я использую ее в цикле for, это не
  • Установка Ruby на Mac OS X
  • Как изменить программу «чтения» по умолчанию?
  • One Solution collect form web for “более длинная строка для tr вызывает зависание и всплеск процессора”

    Основываясь на комментарии @ Barmar о утечке ядровых буферов, я взглянул на текущие не-OS kexts. Я понял, что существует относительно новая из недавней установки BlockBlock ( https://objective-see.com/products/blockblock.html ).

    Удален BlockBlock, перезапущен, и проблема не возникла. Поэтому BlockBlock был виновником в этом деле, и я сообщил об этом автору.

    Однако это не особенно удовлетворительно, так как я использовал метод «догадки и проверки», чтобы понять причину, и, честно говоря, я действительно не понимаю основную причину (с точки зрения ОС), что означает, что я не являюсь -wiser для устранения этой проблемы в будущем.

    Если кто-то сталкивается с этим и может объяснить, что происходит более подробно и обеспечить подход к поиску и устранению неполадок, это будет гораздо лучший ответ, чем «удалить BlockBlock».

    Interesting Posts

    CentOS 6 не регистрирует новое имя хоста в Windows Server 2003

    Почему find иногда соответствует аргументу пути к командной строке?

    Как создать виртуальный интерфейс Ethernet на машине без физического адаптера?

    Как переключиться с CLI на GUI Ubuntu

    Почему root должен запускать неограниченные команды как сам по doas?

    Установите новый дистрибутив Linux без перезагрузки GRUB2

    Команда ls в ftp> не работает!

    Командная строка для перехода в каталог, переданный командой

    Запрашивать bash для получения ответа на завершение команды?

    Почему я не могу использовать тот же каталог для httpd.conf для CentOS и FreeBSD?

    Терминал: запомнить рабочий каталог

    Почему init отключает процесс, если он слишком быстро обновляется?

    iptables ограничивает входящие подключения к контейнеру Docker

    GRUB на MBR внутреннего диска Windows, с дистрибутивами на внешнем диске

    Выключение ПК после приостановления процесса терминала (apt-get upgrade)

    Linux и Unix - лучшая ОС в мире.