утечка памяти с помощью сценария оболочки и tty

Я запускаю сценарий оболочки на малине pi, чтобы общаться с ардуином. Каждый час мой баран израсходован примерно на 50 мегабайт.

Сам скрипт просто подключается к ttyACM0 (USB-терминал arduino), а затем отправляет ему символ. Скрипт работает один раз в минуту, чтобы проверить Temps. Значения для первого аргумента могут быть: 'a', 'b' или 'T'. В случае «a» или «b» он включает / выключает реле. В случае «Т» ардуино возвращает 3 значения температуры, которые я храню.

Сценарий работает нормально (я могу управлять ретрансляцией и принимать значения без перезапуска серийного номера arduinos). но у меня проблемы из-за моей ограниченной памяти.

У меня нет других процессов, запущенных на устройстве, и я уже попробовал новую настройку raspbian.

Может ли кто-нибудь сказать мне, где и если в этом скрипте есть утечки памяти и как я могу их предотвратить?

EDIT: я нашел виновника: скрипт запускает сотни команд «кошки» со временем, как мне избавиться от них? Я уже пробовал killall cat, но это сбрасывает мое серийное соединение с малиной (я хочу запретить это, потому что он «перезапускает» arduino!) @mikeserv указал мне на использование головы, которая автоматически завершает работу после чтения определенного количества строк, к сожалению, это тоже не работает. И я не могу получить температуру, записанную в моем выходном файле без трубы

head -n3 <&3 >>/home/pi/output 

не работает, поскольку он тоже не выходит, и я не получаю никакого вывода

Я могу убить всех кошек каждые несколько минут, чтобы освободить память, но это также сбрасывает мой tty на arduino (так что он перезагружается и теряет состояние для реле)

Edit2: Мне не удалось это сделать (я попробовал несколько возможностей, включая миникомпьютер, экран и т. Д.), Но принимающая часть – это то, где у меня проблемы. Отправка символов ардуино прекрасно работает!

 #!/bin/bash # READ / WRITE ARDUINO exec 3<> /dev/ttyACM0 echo "connected, sleep for 1 sec..." sleep 1 echo "send $1..." echo "$1" >&3 if [ "$1" = "T" ] then cat <&3 | cat >> /home/pi/output &2>1 else echo "nothing to save" fi echo "closing.." exec 3>&- exit 0 

2 Solutions collect form web for “утечка памяти с помощью сценария оболочки и tty”

Когда ты:

 exec 3<> /dev/ttyACM0 

… вы открываете файл-дескриптор чтения / записи в серийный номер tty 3 на 3, который автоматически унаследован дочерними элементами – например, клонированные подоболочки – и именно поэтому вы можете прочитать его с cat <&3 позже в своем фоновом конвейере.

Дело в том, что, поскольку вы используете конвейер – который помещает его и все связанные подоболочки в отдельную группу процессов – он не закрыт для процессов конвейера позже, когда вы …

 exec 3<&- 

… и закройте этот дескриптор для текущих процессов оболочки скрипта. Вместо…

 cat </dev/ttyACM0 | cat >> file & 

… висит в фоновом режиме, ничего не читая до тех пор, пока нет ничего, что нужно прочитать, и сохраняя открытую линию на этом tty все время. Это происходит потому, что cat только закрывает свой вход на EOF, который в этом случае он никогда не получает.

Ты можешь сделать:

 cat /dev/tty 

… в вашем приглашении приблизиться к этому поведению.

То, что вы должны делать, явно уходит от ввода, как только вы читаете столько, сколько вам нужно, или же явно убиваете cat после этого. Вы можете сделать это так:

 head -n"$GUARANTEED_NUM_AVAIL_INPUT LINES" <&3 >>file 

… или с sed [num]q или аналогичным. Таким образом, вы должны избегать необходимости вообще использовать |pipe и, возможно, полностью исключить & backgrounding. Else, чтобы убить cat вы можете сделать:

 cat <&3 >>file & sleep 1 && kill "$!" 

… но, вероятно, это необязательно, так как выход из ввода намного проще.

Стоит отметить, что ваш скрипт уже полностью составлен из портативного синтаксиса, поэтому, вероятно, стоит потратить время на изменение строки #!/bin/bash и вместо этого вызвать более легкую и, скорее всего, более быструю оболочку вместо. Я рекомендую dash для чего-то вроде этого. Посмотрите здесь, если вы заинтересованы в этой линии мышления для q & a при сравнении производительности между различными оболочками – чтобы включить как bash и dash .

Я не могу написать вам исправление, но я могу объяснить, что происходит.

  1. Вы открываете Порт.
  2. Ваши контрольные / отправные значения из датчика температуры.
  3. Вы закрываете порт.

Некоторые возможности:

  • Буфер USB из Arduino заполняется, пока вы не перезапустите скрипт, но буфер по-прежнему заполнен последним прогоном. Вы непреднамеренно вызывают переполнение буфера в Comm Comm, поскольку количество предыдущих запусков накапливается в буфере.
  • Такая же проблема возникает в малине Pi, так как буфер заполняется одинаково с другого направления.

Вам нужно найти способ очистить буфер с обеих сторон, чтобы ворота открывались, посылали 3, закрывали, открывали, отправляли 3 и закрывали и т. Д. Подселлинг, как предлагает Йети, является одним из способов. Я уверен, что есть другие, такие как закрытие и повторное открытие буфера, но не убийство CommPort. Поскольку я не эксперт в Comm Drivers, я могу предложить только теорию.

Обновить

 If [ "$1" = "T" ] then cat <&3 | cat >> /home/pi/output &2>1 cat <&3 | cat >> /dev/null else echo "nothing to save" cat <&3 | cat >> /dev/null fi 
  • экрана по сравнению с открытием виртуальных консолей
  • Почему атрибуты терминала отличаются друг от друга?
  • Измените количество сгенерированных устройств / dev / tty
  • Как предотвратить переключение CTS при каждом открытии или закрытии tty?
  • Исходный код скорости последовательного порта
  • Как я могу жить - измените строки и столбцы TTY?
  • Нет места на ep ring?
  • Могу ли я подключиться к физическому терминалу любого компьютера без монитора
  • socat - регистрация и перенаправление UART
  • Как я могу заставить консоль выводить что-то другое, чем фреймбуфер?
  • Есть ли способ добавить некоторую информацию о времени / дате в приглашение TTY?
  • Доступ к более высоким TTY и роли getty
  • Interesting Posts

    stat на зашифрованном томе в osx занимает много времени

    Этимология «дескриптора» в «файловом дескрипторе»

    Какой хороший легкий вес для работы на старом оборудовании?

    Автоматическая установка Centos7 (PXE) заканчивается при загрузке в live-DVD-вход

    Если многодисковый LVM не использует все пространство?

    Raspberry Pi 3 TP-LINK AC 600 (T2UH) беспроводной USB-адаптер (Raspbian Lite)

    Как написать команду для ключа Exec в файле .desktop, содержащем зарезервированный символ, правильно?

    Изменить разделитель полей в таблице

    PDF-просмотрщик текстовых документов, сохраненных как изображения – плохой рендеринг

    В tmux.conf задайте опцию по-другому, если window_index равно 0?

    Возможности исполняемой символической ссылки на неисполняемый файл в Linux?

    Память RES больше, чем начальная и максимальная память для java

    Могу ли я пропустить проверку принудительной файловой системы?

    Поиск пароля root

    Шифрованный USB-накопитель с системой SSH-ключей

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