Основы Linux. Часть 18 (запуск задач по расписанию)

Android основан на ядре Linux, включает в себя набор стандартных UNIX-команд и простой шелл sh. Все это значит, что мы можем не только использовать командную строку для выполнения низкоуровневых операций, но и писать шелл-скрипты, которые будут выполнять функции, недоступные из графического интерфейса. В этой статье мы поговорим о том, что с их помощью можно сделать и зачем все это нужно.

Чтение из STDIN

Это общепринятое в Linux для труб серии простой, одной цели команды вместе , чтобы создать большее решение , отвечающее наши точные потребности. Способность делать это — одна из реальных задач Linux. Оказывается, мы можем легко разместить этот механизм и с нашими скриптами. Поступая таким образом, мы можем создавать скрипты, которые действуют как фильтры для изменения данных по определенным для нас способам.

Баш вмещает трубопроводы и перенаправление посредством специальных файлов. Каждый процесс получает собственный набор файлов (один для STDIN, STDOUT и STDERR соответственно), и они связаны при вызове или перенаправлении. Каждый процесс получает следующие файлы:

  • STDIN — /proc/<processID>/fd/0
  • STDOUT — /proc/<processID>/fd/1
  • STDERR — /proc/<processID>/fd/2

Чтобы сделать жизнь более удобной, система создает для нас несколько ярлыков:

  • STDIN — /dev/stdin or /proc/self/fd/0
  • STDOUT — /dev/stdout or /proc/self/fd/1
  • STDERR — /dev/stderr or /proc/self/fd/2

fd в дорожках выше обозначает дескриптор файла.

Чтение из STDIN

Поэтому, если мы хотим, чтобы наш скрипт мог обрабатывать данные, которые были отправлены на него, все, что нам нужно сделать, это прочитать соответствующий файл. Все файлы, упомянутые выше, ведут себя как обычные файлы.

summary

Shell #!/bin/bash # Основное резюме моего отчета о продажах echo Here is a summary of the sales data: echo ==================================== echo cat /dev/stdin | cut -d’ ‘ -f 2,3 | sort

12345678 #!/bin/bash# Основное резюме моего отчета о продажах echo Here is a summary of the sales data:echo ====================================echo cat /dev/stdin | cut d‘ ‘ f 2,3 | sort

Давайте разберем это:

  • Строки 4, 5, 6 — Распечатайте заголовок для вывода
  • Строка 8 — cat файл, представляющий STDIN, вырезает установку разделителя на пробел, поля 2 и 3 затем сортируют вывод.
Читайте также:  Запасливый пингвин. Программы для резервного копирования в Linux

Шаг Открываем crontab

Давайте откроем его и посмотрим что же у него внутри. Это делается с помощью любого текстового редактора, но в этой статье мы будем использовать графический текстовый редактор, устанавливаемый в Kali по умолчанию — Leafpad. Введите в консоли:

leafpad /etc/crontab

Шаг Открываем crontab

Версия Debian, на которой основан Kali, имеет новую версию crontab, с которой легче работать, чем с ранними версиями. В отличие от предыдущих версий, разработчики поставили для полей поясняющие метки и добавили новое поле для обозначения пользователя, который и будет запускать задание.

Первый пример

Теперь давайте попробуем написать первый скрипт. Делать это лучше на компе, а еще лучше в Linux или редакторе, который умеет создавать текстовые файлы без символа возврата каретки (который при открытии в Android будет выглядеть как ^M в конце каждой строки). Наш первый скрипт будет состоять всего из двух строк, которые делают бэкап всех установленных приложений на карту памяти. Его код (требует BusyBox):

#!/system/bin/sh mkdir /sdcard/backup cp /data/app/*.apk /sdcard/backup

Сохраняем (пусть он называется apk_) и перекидываем на смартфон с помощью ADB:

$ adb push apk_ /sdcard/

Теперь его нужно запустить. Проще всего сделать это с помощью все того же ADB:

$ adb shell sh /sdcard/apk_

Примерно таким же образом скрипт можно запустить из консоли на самом смартфоне/планшете:

$ sh /sdcard/apk_

Само собой, такой способ не очень удобен. Поэтому нам нужен какой-то быстрый способ запуска скрипта. Наиболее удобное из найденных мной решений — это приложение QuickTerminal. Устанавливаем, запускаем, переходим на вкладку Quick Command, нажимаем кнопку «+», вбиваем имя (произвольное) и команду (sh /sdcard/apk_), в поле Output Type выбираем либо Dialog Output, либо Nothing. В первом случае во время выполнения скрипта на экране появится окно с результатом, во втором все пройдет в фоне. Кому что удобнее. Далее сохраняем и получаем кнопку, с помощью которой скрипт можно будет запустить быстро и легко.

Читайте также:  Особенности установки Linux рядом с Windows

Теперь напишем скрипт, который восстановит наш бэкап:

Первый пример

#!/system/bin/sh for i in /sdcard/backup/*; do pm install -t -r $i done

В нем мы задействовали команду pm с опцией install и флагами -t и -r, которые заставляют систему устанавливать приложения, даже если они подписаны тестовым ключом или уже установлены. Также можно использовать флаг -s, который принуждает приложения к установке на карту памяти (если такая возможность есть), или -f — установка во внутреннюю память устройства.

Почти все команды Android имеют подробную справку

Имея рут, можно даже сделать бэкап настроек всех приложений с помощью копирования и архивации каталога /data/data/, однако восстановить его будет очень проблематично, так как в Android каждое приложение исполняется от имени созданного специально для него Linux-юзера и хранит настройки внутри каталога, принадлежащего этому пользователю. Проблема здесь в том, что идентификатор Linux-юзера для каждого приложения генерируется динамически, поэтому после восстановления бэкапа в заново установленной системе идентификаторы не будут совпадать и приложения не смогут прочитать свои настройки. Придется вручную выяснять ID юзера для каждого приложения и менять права доступа на каталоги с данными.

С другой стороны, мы можем использовать встроенный в Android Backup Manager, позволяющий сторонним приложениям использовать возможности системы для бэкапа и восстановления приложений и их данных. Управлять им можно из консоли (а значит, и с помощью скриптов), но сам по себе он никакого бэкапа не производит, а возлагает эту работу на сторонние приложения. Helium — одно из таких приложений. Если установить и настроить его, операцию бэкапа и восстановления можно будет заскриптовать. Например, следующий простой скрипт сделает резервную копию всех сторонних приложений:

#!/system/bin/sh # Получаем список всех сторонних приложений for i in `pm list packages -e`; do # Добавляем каждое из них в очередь bmgr backup ${i:8} done # Запускаем операцию бэкапа bmgr run

Читайте также:  Как управлять файлами в терминале Linux и на рабочем столе

Конструкция ${i:8} здесь нужна, чтобы обрезать слово «packages:», которое pm добавляет в начало имени каждого пакета. Чтобы восстановить бэкап, можно использовать либо тот же Helium, либо команду bmgr:

$ bmgr list sets # Получаем список бэкапов $ bmgr restore <тег> # Восстанавливаем нужный бэкап

Циклы. Цикл for-in.

Оператор for-in предназначен для поочередного обращения к значениям перечисленным в списке. Каждое значение в списке поочерёдно присваивается переменной. Синтаксис следующий:

for переменная in [список_значений] do команды done for NAME [in LIST ]; do COMMANDS; done # синтаксис для записи цикла в одну строку Если ключевое слово do находится в одной строке со словом for, то после списка аргументов (перед do) необходимо ставить точку с запятой.

for arg in [list] ; do

Рассмотрим небольшой пример:

#!/bin/bash for i in 0 1 2 3 4 # переменной $i будем поочерёдно присваивать значения от 0 до 4 включительно do echo "Number is $i" done #цикл окончен exit 0

В переменную $i поочерёдно подставляются значения из списка и в цикле идёт работа со значением этой переменной.

Элементы в списке могут разделяться символами пробела или табуляции. Если список не помещается на одну строку, его можно продолжить на следующей, но перед тем как нажать на Enter, поставьте символ "\" для экранирования значения символа перевода строки.

  • Пример получения данных из внешнего файла с фильтрацией содержимого файла. В нем сначала отбираются первые поля файла (разделение полей — пробел), а затем удаляются комментарии т.е. строки начинающиеся на символ "#".

#!/bin/bash for i in `cat | cut -f1 -d ' ' | sed -e '/^#/ d'` do echo "$i" done exit 0