утечка памяти с помощью сценария оболочки и 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 
  • Запуск удаленной сессии X на локальном tty
  • Есть ли способ reptyr процесса make или любого процесса с подпроцессами?
  • Как получить настоящее имя управляющего терминала?
  • Детский процесс продолжает работать, если родитель умирает
  • Почему я не могу отправлять escape-последовательности с клавиатуры, но могу сделать это из другого tty?
  • Управление буферизацией чата ppp
  • Удалите новую строку перед `/ etc / issue` в tty
  • медленная передача файлов через последовательный порт с кошкой
  • доступ к stdin / stdout процесса, запущенного в другой tty
  • Weird вывод при использовании ssh внутри цикла над файлом
  • Консоль Linux печатает буква «q» в случайном порядке
  • Interesting Posts

    Как использовать команду вставки для многих файлов, имена которых не являются цифрами? (вставьте столбцы из каждого файла в один файл)

    Как записать iptables с ядра 3.9.0?

    Обработка абзацев в файлах unix

    Обновление ядра Linux, оставляя остальную систему как

    Как связать ssh и остаться в подсказке

    Arch Linux, «повесить» на «Достигнутый целевой графический интерфейс»,

    На следующий день пользователя введена дата – дата +1 день

    Могу ли я выполнять команды из полуночного командного ssh-соединения?

    Локальная ошибка в Debian

    медленная передача файлов через последовательный порт с кошкой

    Raspbian: воспроизведение видео через HDMI из командной строки

    Почему я получаю ошибку «/ bin / bash не могу найти команду» для псевдонима?

    Как получить информацию о чтении / записи диска без новых зависимостей?

    Загрузка в режиме спасения с поддержкой vlan в RHEL

    Есть ли способ ссылаться на несколько файлов в каталоге без повторного набора всего пути?

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