Scorpi-ON/linux-shell-labs
Several Linux shell scripts. A set of lab works on Operation Systems (Oct 2023, 5th semester of university).
linux-shell-labs
Набор лабораторных работ по операционным системам, представляющих собой скрипты Linux Shell различной сложности.
Особенности реализации
- Интегрирован ShellCheck для статического анализа скриптов
- Модульная структура для удобного выполнения других вариантов работ
Простые команды
Задание
В соответствии с вариантом задания написать однострочную команду, расширяющую функциональные возможности ОС Unix.
Запуск
Для загрузки команд в оболочку выполните команду из корня репозитория:
source simple.shПосле этого они станут доступны.
Чтобы реализовать поддержку скрытых файлов, везде, где применялась команда ls -l, необходимо дописать флаг -A.
Команды
1. lx — вывести список файлов указанного каталога, у которых права на чтение, запись и выполнение только для создателя файла (т.е. rwx------), отсортировать их по имени в обратном порядке.
Команда ls -lh $1 выводит всё содержание указаного каталога, а grep находит те строки, которые начинаются на -rwx------ (т. е. содержат файлы с требуемым набором прав).
2. pu — посчитать количество процессов, запущенных указанным пользователем.
Команда ps с аргументом -u выводит список процессов, запущенных указанным пользователем. Модификатор h убирает заголовок перед списком. Для подсчёта остаётся вызвать команду wc. Флаг -l, означает подсчёт только строк (а не слов и символов).
3. pt — посчитать кол-во процессов, запущенных с указанного терминала.
Команда ps c модификатором t выводит список процессов, запущенных с указанного терминала. Для подсчёта вновь используем модификатор h и передачу команде wc.
4. nx — количество исполнимых файлов в указанном каталоге.
С помощью ls -l $1 выведем содержимое указанного каталога. Командой grep с шаблоном «^-.x. » найдём все строки, начинающиеся на - (такие строки описывают файлы) и содержащие x в триадах прав (хотя бы одна x означает, что файл является исполняемым для одной из групп пользователей). Флаг -с команды grep означает, что нужно вывести только число найденных строк.
5. npu — посчитать количество терминированных процессов, запущенных указанным пользователем.
Терминированные процессы имеют статус T в списке процессов. Поскольку нам необходимо узнать их количество, воспользуемся аргументом -o и передадим ему одно поле — stat (статус процесса). Аргумент -u $1 выведет процессы указанного пользователя. Остаётся найти количество нужных статусов при помощи grep -c ‘^T’.
На скриншоте было создано и прервано 3 процесса, чтобы продемонстрировать работу скрипта.
6. mp — количество процессов, запущенных определенного числа.
Запустим команду ps с модификатором h и флагом е для получения всех процессов без строки заголовка. Чтобы выбрать только даты, добавим аргументы -o lstart и -D %d.%m.%y. Теперь для поиска и подсчёта можно вводить дату в привычном формате.
7. tu — посчитать количество терминалов, с которых запущены процессы в текущий момент времени.
Команда who в числе прочих данных выводит список активных терминалов. Подсчитаем их с помощью wc -l. При этом, поскольку с терминала pts/0 процессы не запускаются, отнимем от подсчитанного значения 1. Остаётся только вывести полученное арифметическое выражение с помощью echo.
8. bp — вывести информацию об указанном количестве процессов, имеющих наибольшее время использования процессора.
Выведем список всех процессов командой ps -e. Также после аргумента -o укажем необходимые поля для вывода: пользователь, идентификатор процесса, процессорное время и команда. Чтобы отсортировать список по процессорному времени по убыванию используем аргумент --sort=-time. Чтобы вывести указанное количество строк из полученного списка, используем команду head. Аргумент -n задаёт число строк для вывода. Поскольку строка заголовка в данном случае нужна, к указанному числу прибавим 1.
9. bf — вывести информацию об указанном количестве файлов, имеющих наибольший размер.
С помощью флага -S отсортируем вывод команды ls -lh по размеру файлов. Чтобы отобрать файлы из содержимого каталога, применим grep ‘^-‘. Чтобы выбрать только указанное количество файлов из топа, используем head -n $2.
10. fm — посчитать кол-во директорий в указанном каталоге, у которых права доступа: rwxrwxrwx.
Выведем содержимое указанного каталога, после чего используем grep с шаблоном ‘^drwxrwxrwx’ (выбирает директории с полной триадой прав) и подсчитаем с помощью флага -c.
11. ml — вывести информацию об указанном количестве файлов, имеющих наибольшее число связей.
Число связей файлов выводится во втором столбце вывода команды ls -l. Поэтому, чтобы отсортировать файлы и директории по числу связей, передадим команде sort аргументы -rnk2 (числовая сортировка по убыванию по второму столбцу). Чтобы получить указанное количество файлов, применим команду head.
12. ll — список пользователей-владельцев файлов в указанном каталоге.
Чтобы вычленить пользователей владельцев из содержимого каталога, применим команду awk. Чтобы выбрать из них уникальные имена, используем sort -u.
13. rl — вывести список всех файлов, с датой создания, равной текущему числу.
Для вывода содержимого каталога с датой создания применим аргумент --time=creation, а чтобы эта дата была в более привычном формате, добавим аргумент --time-style +%d.%m.%y. Текущую дату получим в этом же формате командой date. Остаётся только найти строчки, содержащие эту дату (а также - в начале строки как признак файла), при помощи grep.
14. lr — вывести 5 последних процессов, запущенных root.
По аналогии с командой bp (см. пункт 8) выведем интересующие нас колонки процессов root и с помощью аргумента --sort=-start отсортируем по времени создания по убыванию.
15. rc — вывести 5 процессов, запущенных studentom.
Выведем все процессы, запущенные указанным пользователем, после чего выберем 5 из них (а также строку заголовка).
16. cu — посчитать, какое количество пользователей сейчас работает в системе (имя уникально).
Выведем работающих на данный момент пользователей командой w, отбросим строку заголовка флагом -h и подсчитаем оставшиеся строки пользователей.
Сложные скрипты
Задание
Разработать программу-скрипт средствами Shell. Программа должна запускаться в следующем формате: ./script.sh Time NumItem ItemFile, где:
- Тime — длительность промежутка времени;
- Numltem — количество пунктов меню;
- ItemFile — текстовый файл с наименованием пунктов меню.
Скрипт должен выполнять следующие действия:
- При запуске контролировать наличие необходимых параметров и при необходимости выдавать сообщение об ошибке.
- Выводить сообщение-подсказку о выполняемом задании.
- Формировать меню с требуемым количеством пунктов. Информация о названии пунктов берется из текстового конфигурационного файла.
- Реализовывать выполнение пунктов меню в соответствии с индивидуальным заданием.
- Для периодических действий период повтора брать из параметра Time.
- Результаты выполнения должны выводится на экран в формате:
----------------------------Дата---Время----------------------------
Результаты
--------------------------------------------------------------------
- Предусмотреть выход из скрипта по заданному условию и возврат в главное меню программы.
- При необходимости параметры работы скрипта могут вводится в диалоговом режиме.
- Все действия, производимые скриптом фиксировать в файле журнала.
Запуск
Для запуска скрипта нужного варианта выполните следующие команды из корня репозитория:
LAB_VARIANT=<НОМЕР_ВАРИАНТА>
chmod +x complex/$LAB_VARIANT/main.sh
./complex/$LAB_VARIANT/main.shСкрипты
- Поиск в двух указанных каталогах файлов с одинаковым содержимым. Вывод имен этих файлов и размера в строках.
- Создание в текущем каталоге папки вида data-time до тех пор, пока в текущем каталоге не появится файл с именем stop. В каждую папку копировать из текущего каталога файлы, заканчивающиеся на символы а — в первую папку, b — во вторую папку и т. д.
- При выходе удаление всех созданных папок и создание файла, в который записывается их количество.
Пример лога
[<ДАТА И ВРЕМЯ>] <ВЫЗОВ ФУНКЦИИ ИЛИ ФАЙЛА С АРГУМЕНТАМИ>
<СООБЩЕНИЕ>
[28.10.2023 22:05:53] <одна из библиотек>
Создаём файл лога
[28.10.2023 22:05:53] <одна из библиотек>
Найдено 3 запрограммированных действий по варианту: sizeDifference analyzeProcessCountChanging listNewProcesses
[28.10.2023 22:05:53] ./main.sh "3" "3" "menu"
Проверим аргументы скрипта на корректность
[28.10.2023 22:05:53] isIntBetween "3" "длительность промежутка времени в секундах" "1"
Проверим, является ли "3" числовым значением
[28.10.2023 22:05:53]
Проверим, лежит ли 3 между min=1 и max=
[28.10.2023 22:05:53] isIntBetween "3" "максимальное количество пунктов меню" "3"
Проверим, является ли "3" числовым значением
[28.10.2023 22:05:53]
Проверим, лежит ли 3 между min=3 и max=
[28.10.2023 22:05:53] ./main.sh "3" "3" "menu"
Проверим, доступен ли файл "menu" для чтения
[28.10.2023 22:05:53] ./main.sh "3" "3" "menu"
Первоначальная настройка завершена, переходим в основной цикл
[28.10.2023 22:05:53] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:05:53] _menuItems
Прочитаем и выведем 3 строк файла "menu"
[28.10.2023 22:05:53]
Выведено 3 пунктов меню
[28.10.2023 22:05:53] ./main.sh
Считаем символ для выбора пункта меню
[28.10.2023 22:05:53] readTillCorrectResult "_readNum" "пункт меню"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:05:59]
Считан символ '1'. Проверим, является ли он номером одного из пунктов меню
[28.10.2023 22:05:59] isIntBetween "1" "пункт меню" "1" "3"
Проверим, является ли "1" числовым значением
[28.10.2023 22:05:59]
Проверим, лежит ли 1 между min=1 и max=3
[28.10.2023 22:05:59] _readNum
Сделаем пункт меню индексом (уменьшим на 1), чтобы обращаться по нему к массиву действий
[28.10.2023 22:05:59] readTillCorrectResult "_readNum" "пункт меню"
Считывание прошло успешно
[28.10.2023 22:05:59] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:05:59] ./main.sh "3" "3" "menu"
Начинаем выполнение действия "sizeDifference"
[28.10.2023 22:05:59] sizeDifference
Считаем папку для проверки
[28.10.2023 22:05:59] readTillCorrectResult "_readDirectory" "папку для поиска файлов по подкаталогам"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:06:07] _readDirectory
Считано значение "/home/scorpion". Проверим, папка ли это
[28.10.2023 22:06:07]
Теперь проверим, содержит ли она подкаталоги для проверки
[28.10.2023 22:06:07] readTillCorrectResult "_readDirectory" "папку для поиска файлов по подкаталогам"
Считывание прошло успешно
[28.10.2023 22:06:07] sizeDifference
Найдём подкаталоги 1-го уровня данной папки
[28.10.2023 22:06:07]
Начинаем просмотр каждого из них
[28.10.2023 22:06:07]
".config": 112510389 - 0 = 112510389
[28.10.2023 22:06:07]
".local": 127916928 - 0 = 127916928
[28.10.2023 22:06:07]
".cache": 255842149 - 0 = 255842149
[28.10.2023 22:06:07]
"Desktop" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
".yandex": 580 - 38 = 542
[28.10.2023 22:06:07]
".pki": 36864 - 449 = 36415
[28.10.2023 22:06:07]
".vscode": 119869456 - 0 = 119869456
[28.10.2023 22:06:07]
".gnome": 354 - 326 = 28
[28.10.2023 22:06:07]
".designer": 16718 - 848 = 15870
[28.10.2023 22:06:07]
".cargo": 239662666 - 0 = 239662666
[28.10.2023 22:06:07]
".java": 148572 - 0 = 148572
[28.10.2023 22:06:07]
".android": 1704 - 12 = 1692
[28.10.2023 22:06:07]
".jdks": 130326280 - 11 = 130326269
[28.10.2023 22:06:07]
".m2": 575854 - 40 = 575814
[28.10.2023 22:06:07]
".pgadmin": 61440 - 0 = 61440
[28.10.2023 22:06:07]
".swt" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
"Загрузки" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
"Документы" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
"Изображения" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
"Видео" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07] ./main.sh "3" "3" "menu"
Действие "sizeDifference" завершено
[28.10.2023 22:06:07] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:06:07] _menuItems
Прочитаем и выведем 3 строк файла "menu"
[28.10.2023 22:06:07]
Выведено 3 пунктов меню
[28.10.2023 22:06:07] ./main.sh
Считаем символ для выбора пункта меню
[28.10.2023 22:06:07] readTillCorrectResult "_readNum" "пункт меню"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:07:02]
Считан символ '2'. Проверим, является ли он номером одного из пунктов меню
[28.10.2023 22:07:02] isIntBetween "2" "пункт меню" "1" "3"
Проверим, является ли "2" числовым значением
[28.10.2023 22:07:02]
Проверим, лежит ли 2 между min=1 и max=3
[28.10.2023 22:07:02] _readNum
Сделаем пункт меню индексом (уменьшим на 1), чтобы обращаться по нему к массиву действий
[28.10.2023 22:07:02] readTillCorrectResult "_readNum" "пункт меню"
Считывание прошло успешно
[28.10.2023 22:07:02] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:07:02] ./main.sh "3" "3" "menu"
Начинаем выполнение действия "analyzeProcessCountChanging"
[28.10.2023 22:07:02] analyzeProcessCountChanging
Считаем пользователя и предел процессов
[28.10.2023 22:07:02] readTillCorrectResult "_readUser" "имя пользователя, процессы которого нужно сканировать"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:07:06] _readUser
Считано значение "noname". Проверим, пользователь ли это
[28.10.2023 22:07:06]
Нет, такого пользователя не существует
[28.10.2023 22:07:06] readTillCorrectResult "_readUser" "имя пользователя, процессы которого нужно сканировать"
Функция считывания завершилась с ошибкой, запускаем ещё раз
[28.10.2023 22:07:12] _readUser
Считано значение "scorpion". Проверим, пользователь ли это
[28.10.2023 22:07:12] readTillCorrectResult "_readUser" "имя пользователя, процессы которого нужно сканировать"
Считывание прошло успешно
[28.10.2023 22:07:12] readTillCorrectResult "_readProcessLimit" "предел процессов, при достижении которого необходимо прервать сканирование"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:07:15] _readProcessLimit
Считано значение "0". Проверим, положительное ли это число
[28.10.2023 22:07:15] isIntBetween "0" "предел процессов" "1"
Проверим, является ли "0" числовым значением
[28.10.2023 22:07:15]
Проверим, лежит ли 0 между min=1 и max=
[28.10.2023 22:07:15]
Нет, не лежит
[28.10.2023 22:07:15] readTillCorrectResult "_readProcessLimit" "предел процессов, при достижении которого необходимо прервать сканирование"
Функция считывания завершилась с ошибкой, запускаем ещё раз
[28.10.2023 22:07:28] _readProcessLimit
Считано значение "160". Проверим, положительное ли это число
[28.10.2023 22:07:28] isIntBetween "160" "предел процессов" "1"
Проверим, является ли "160" числовым значением
[28.10.2023 22:07:28]
Проверим, лежит ли 160 между min=1 и max=
[28.10.2023 22:07:28] readTillCorrectResult "_readProcessLimit" "предел процессов, при достижении которого необходимо прервать сканирование"
Считывание прошло успешно
[28.10.2023 22:07:28] analyzeProcessCountChanging
Начинаем проверку числа процессов пользователя scorpion с интервалом 3 секунд
[28.10.2023 22:07:28] analyzeProcessCountChanging
Найдено 100 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:28] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 100, а максимальное значение 160
[28.10.2023 22:07:28]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:28] _divAndRound "1000" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:28]
Разделив делимое 1000 на делитель 160 нацело, получаем 6
[28.10.2023 22:07:28]
Разделим делимое 1000 на делитель 160 с остатком, получаем 40
[28.10.2023 22:07:28]
Разделим остаток 40, умноженный на 10, на делитель 160 нацело, получаем 2 — разряд десятых частного
[28.10.2023 22:07:28]
Округляя частное 6,2 до целых, разряд десятых отбрасываем, поскольку 2 < 5
[28.10.2023 22:07:28]
Добавим незаполненную часть из 4 ячеек в прогрессбар
[28.10.2023 22:07:28]
Добавим заполненную часть из 6 ячеек в начало прогрессбара.
[28.10.2023 22:07:28]
Итоговый прогрессбар: ******————
[28.10.2023 22:07:31] analyzeProcessCountChanging
Найдено 100 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:31] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 100, а максимальное значение 160
[28.10.2023 22:07:31]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:31] _divAndRound "1000" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:31]
Разделив делимое 1000 на делитель 160 нацело, получаем 6
[28.10.2023 22:07:31]
Разделим делимое 1000 на делитель 160 с остатком, получаем 40
[28.10.2023 22:07:31]
Разделим остаток 40, умноженный на 10, на делитель 160 нацело, получаем 2 — разряд десятых частного
[28.10.2023 22:07:31]
Округляя частное 6,2 до целых, разряд десятых отбрасываем, поскольку 2 < 5
[28.10.2023 22:07:31]
Добавим незаполненную часть из 4 ячеек в прогрессбар
[28.10.2023 22:07:31]
Добавим заполненную часть из 6 ячеек в начало прогрессбара.
[28.10.2023 22:07:31]
Итоговый прогрессбар: ******————
[28.10.2023 22:07:34] analyzeProcessCountChanging
Найдено 104 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:34] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 104, а максимальное значение 160
[28.10.2023 22:07:34]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:34] _divAndRound "1040" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:34]
Разделив делимое 1040 на делитель 160 нацело, получаем 6
[28.10.2023 22:07:34]
Разделим делимое 1040 на делитель 160 с остатком, получаем 80
[28.10.2023 22:07:34]
Разделим остаток 80, умноженный на 10, на делитель 160 нацело, получаем 5 — разряд десятых частного
[28.10.2023 22:07:34]
Округляя частное 6,5 до целых, увеличиваем целую часть на 1, поскольку 5 ≥ 5
[28.10.2023 22:07:34]
Добавим незаполненную часть из 3 ячеек в прогрессбар
[28.10.2023 22:07:34]
Добавим заполненную часть из 7 ячеек в начало прогрессбара.
[28.10.2023 22:07:34]
Итоговый прогрессбар: *******———
[28.10.2023 22:07:37] analyzeProcessCountChanging
Найдено 126 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:37] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 126, а максимальное значение 160
[28.10.2023 22:07:37]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:37] _divAndRound "1260" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:37]
Разделив делимое 1260 на делитель 160 нацело, получаем 7
[28.10.2023 22:07:37]
Разделим делимое 1260 на делитель 160 с остатком, получаем 140
[28.10.2023 22:07:37]
Разделим остаток 140, умноженный на 10, на делитель 160 нацело, получаем 8 — разряд десятых частного
[28.10.2023 22:07:37]
Округляя частное 7,8 до целых, увеличиваем целую часть на 1, поскольку 8 ≥ 5
[28.10.2023 22:07:37]
Добавим незаполненную часть из 2 ячеек в прогрессбар
[28.10.2023 22:07:37]
Добавим заполненную часть из 8 ячеек в начало прогрессбара.
[28.10.2023 22:07:37]
Итоговый прогрессбар: ********——
[28.10.2023 22:07:40] analyzeProcessCountChanging
Найдено 146 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:40] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 146, а максимальное значение 160
[28.10.2023 22:07:40]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:40] _divAndRound "1460" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:40]
Разделив делимое 1460 на делитель 160 нацело, получаем 9
[28.10.2023 22:07:40]
Разделим делимое 1460 на делитель 160 с остатком, получаем 20
[28.10.2023 22:07:40]
Разделим остаток 20, умноженный на 10, на делитель 160 нацело, получаем 1 — разряд десятых частного
[28.10.2023 22:07:40]
Округляя частное 9,1 до целых, разряд десятых отбрасываем, поскольку 1 < 5
[28.10.2023 22:07:40]
Добавим незаполненную часть из 1 ячеек в прогрессбар
[28.10.2023 22:07:40]
Добавим заполненную часть из 9 ячеек в начало прогрессбара.
[28.10.2023 22:07:40]
Итоговый прогрессбар: *********—
[28.10.2023 22:07:43] analyzeProcessCountChanging
Найдено 166 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:43] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 166, а максимальное значение 160
[28.10.2023 22:07:43]
Текущее значение не меньше, чем максимальное. Значит, он будет заполнен полностью
[28.10.2023 22:07:43]
Текущее значение превышает максимальное. Добавим в прогрессбар символ '>', свидетельствующий об этом
[28.10.2023 22:07:43]
Добавим заполненную часть из 10 ячеек в начало прогрессбара.
[28.10.2023 22:07:43]
Итоговый прогрессбар: **********>
[28.10.2023 22:07:46] analyzeProcessCountChanging
Предел числа процессов (160) достигнут
[28.10.2023 22:07:46] ./main.sh "3" "3" "menu"
Действие "analyzeProcessCountChanging" завершено
[28.10.2023 22:07:46] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:07:46] _menuItems
Прочитаем и выведем 3 строк файла "menu"
[28.10.2023 22:07:46]
Выведено 3 пунктов меню
[28.10.2023 22:07:46] ./main.sh
Считаем символ для выбора пункта меню
[28.10.2023 22:07:46] readTillCorrectResult "_readNum" "пункт меню"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:08:09]
Считан символ '3'. Проверим, является ли он номером одного из пунктов меню
[28.10.2023 22:08:09] isIntBetween "3" "пункт меню" "1" "3"
Проверим, является ли "3" числовым значением
[28.10.2023 22:08:09]
Проверим, лежит ли 3 между min=1 и max=3
[28.10.2023 22:08:09] _readNum
Сделаем пункт меню индексом (уменьшим на 1), чтобы обращаться по нему к массиву действий
[28.10.2023 22:08:09] readTillCorrectResult "_readNum" "пункт меню"
Считывание прошло успешно
[28.10.2023 22:08:09] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:08:09] ./main.sh "3" "3" "menu"
Начинаем выполнение действия "listNewProcesses"
[28.10.2023 22:08:09] listNewProcesses
Получаем общий список процессов
[28.10.2023 22:08:09] listNewProcesses
Выводим только те процессы из списка, которые появились после запуска скрипта (PID которого 216862)
[28.10.2023 22:08:09] ./main.sh "3" "3" "menu"
Действие "listNewProcesses" завершено
[28.10.2023 22:08:09] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:08:09] ./main.sh
Выходим из основного цикла
- Определить разность между максимальным и минимальным размерами файлов во всех подкаталогах указанного каталога.
- Анализировать изменение количества процессов запущенных указанным пользователем в системе. Результат выводить в виде диаграммы вида:
**** 4 процесса
** 2 процесса
****** 6 процессов
*** 3 процесса
* 1 процесс
* 1 процесс
** 2 процесса
и т. д. В начале каждой строки выводить текущее время.
Выход при превышении количества процессов некоторой заданной границы.
- При выходе из программы формирование списка процессов, появившихся в системе за время работы скрипта.
Пример лога
[<ДАТА И ВРЕМЯ>] <ВЫЗОВ ФУНКЦИИ ИЛИ ФАЙЛА С АРГУМЕНТАМИ>
<СООБЩЕНИЕ>
[28.10.2023 22:05:53] <одна из библиотек>
Создаём файл лога
[28.10.2023 22:05:53] <одна из библиотек>
Найдено 3 запрограммированных действий по варианту: sizeDifference analyzeProcessCountChanging listNewProcesses
[28.10.2023 22:05:53] ./main.sh "3" "3" "menu"
Проверим аргументы скрипта на корректность
[28.10.2023 22:05:53] isIntBetween "3" "длительность промежутка времени в секундах" "1"
Проверим, является ли "3" числовым значением
[28.10.2023 22:05:53]
Проверим, лежит ли 3 между min=1 и max=
[28.10.2023 22:05:53] isIntBetween "3" "максимальное количество пунктов меню" "3"
Проверим, является ли "3" числовым значением
[28.10.2023 22:05:53]
Проверим, лежит ли 3 между min=3 и max=
[28.10.2023 22:05:53] ./main.sh "3" "3" "menu"
Проверим, доступен ли файл "menu" для чтения
[28.10.2023 22:05:53] ./main.sh "3" "3" "menu"
Первоначальная настройка завершена, переходим в основной цикл
[28.10.2023 22:05:53] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:05:53] _menuItems
Прочитаем и выведем 3 строк файла "menu"
[28.10.2023 22:05:53]
Выведено 3 пунктов меню
[28.10.2023 22:05:53] ./main.sh
Считаем символ для выбора пункта меню
[28.10.2023 22:05:53] readTillCorrectResult "_readNum" "пункт меню"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:05:59]
Считан символ '1'. Проверим, является ли он номером одного из пунктов меню
[28.10.2023 22:05:59] isIntBetween "1" "пункт меню" "1" "3"
Проверим, является ли "1" числовым значением
[28.10.2023 22:05:59]
Проверим, лежит ли 1 между min=1 и max=3
[28.10.2023 22:05:59] _readNum
Сделаем пункт меню индексом (уменьшим на 1), чтобы обращаться по нему к массиву действий
[28.10.2023 22:05:59] readTillCorrectResult "_readNum" "пункт меню"
Считывание прошло успешно
[28.10.2023 22:05:59] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:05:59] ./main.sh "3" "3" "menu"
Начинаем выполнение действия "sizeDifference"
[28.10.2023 22:05:59] sizeDifference
Считаем папку для проверки
[28.10.2023 22:05:59] readTillCorrectResult "_readDirectory" "папку для поиска файлов по подкаталогам"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:06:07] _readDirectory
Считано значение "/home/scorpion". Проверим, папка ли это
[28.10.2023 22:06:07]
Теперь проверим, содержит ли она подкаталоги для проверки
[28.10.2023 22:06:07] readTillCorrectResult "_readDirectory" "папку для поиска файлов по подкаталогам"
Считывание прошло успешно
[28.10.2023 22:06:07] sizeDifference
Найдём подкаталоги 1-го уровня данной папки
[28.10.2023 22:06:07]
Начинаем просмотр каждого из них
[28.10.2023 22:06:07]
".config": 112510389 - 0 = 112510389
[28.10.2023 22:06:07]
".local": 127916928 - 0 = 127916928
[28.10.2023 22:06:07]
".cache": 255842149 - 0 = 255842149
[28.10.2023 22:06:07]
"Desktop" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
".yandex": 580 - 38 = 542
[28.10.2023 22:06:07]
".pki": 36864 - 449 = 36415
[28.10.2023 22:06:07]
".vscode": 119869456 - 0 = 119869456
[28.10.2023 22:06:07]
".gnome": 354 - 326 = 28
[28.10.2023 22:06:07]
".designer": 16718 - 848 = 15870
[28.10.2023 22:06:07]
".cargo": 239662666 - 0 = 239662666
[28.10.2023 22:06:07]
".java": 148572 - 0 = 148572
[28.10.2023 22:06:07]
".android": 1704 - 12 = 1692
[28.10.2023 22:06:07]
".jdks": 130326280 - 11 = 130326269
[28.10.2023 22:06:07]
".m2": 575854 - 40 = 575814
[28.10.2023 22:06:07]
".pgadmin": 61440 - 0 = 61440
[28.10.2023 22:06:07]
".swt" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
"Загрузки" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
"Документы" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
"Изображения" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07]
"Видео" — содержит менее двух файлов, невозможно получить разность
[28.10.2023 22:06:07] ./main.sh "3" "3" "menu"
Действие "sizeDifference" завершено
[28.10.2023 22:06:07] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:06:07] _menuItems
Прочитаем и выведем 3 строк файла "menu"
[28.10.2023 22:06:07]
Выведено 3 пунктов меню
[28.10.2023 22:06:07] ./main.sh
Считаем символ для выбора пункта меню
[28.10.2023 22:06:07] readTillCorrectResult "_readNum" "пункт меню"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:07:02]
Считан символ '2'. Проверим, является ли он номером одного из пунктов меню
[28.10.2023 22:07:02] isIntBetween "2" "пункт меню" "1" "3"
Проверим, является ли "2" числовым значением
[28.10.2023 22:07:02]
Проверим, лежит ли 2 между min=1 и max=3
[28.10.2023 22:07:02] _readNum
Сделаем пункт меню индексом (уменьшим на 1), чтобы обращаться по нему к массиву действий
[28.10.2023 22:07:02] readTillCorrectResult "_readNum" "пункт меню"
Считывание прошло успешно
[28.10.2023 22:07:02] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:07:02] ./main.sh "3" "3" "menu"
Начинаем выполнение действия "analyzeProcessCountChanging"
[28.10.2023 22:07:02] analyzeProcessCountChanging
Считаем пользователя и предел процессов
[28.10.2023 22:07:02] readTillCorrectResult "_readUser" "имя пользователя, процессы которого нужно сканировать"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:07:06] _readUser
Считано значение "noname". Проверим, пользователь ли это
[28.10.2023 22:07:06]
Нет, такого пользователя не существует
[28.10.2023 22:07:06] readTillCorrectResult "_readUser" "имя пользователя, процессы которого нужно сканировать"
Функция считывания завершилась с ошибкой, запускаем ещё раз
[28.10.2023 22:07:12] _readUser
Считано значение "scorpion". Проверим, пользователь ли это
[28.10.2023 22:07:12] readTillCorrectResult "_readUser" "имя пользователя, процессы которого нужно сканировать"
Считывание прошло успешно
[28.10.2023 22:07:12] readTillCorrectResult "_readProcessLimit" "предел процессов, при достижении которого необходимо прервать сканирование"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:07:15] _readProcessLimit
Считано значение "0". Проверим, положительное ли это число
[28.10.2023 22:07:15] isIntBetween "0" "предел процессов" "1"
Проверим, является ли "0" числовым значением
[28.10.2023 22:07:15]
Проверим, лежит ли 0 между min=1 и max=
[28.10.2023 22:07:15]
Нет, не лежит
[28.10.2023 22:07:15] readTillCorrectResult "_readProcessLimit" "предел процессов, при достижении которого необходимо прервать сканирование"
Функция считывания завершилась с ошибкой, запускаем ещё раз
[28.10.2023 22:07:28] _readProcessLimit
Считано значение "160". Проверим, положительное ли это число
[28.10.2023 22:07:28] isIntBetween "160" "предел процессов" "1"
Проверим, является ли "160" числовым значением
[28.10.2023 22:07:28]
Проверим, лежит ли 160 между min=1 и max=
[28.10.2023 22:07:28] readTillCorrectResult "_readProcessLimit" "предел процессов, при достижении которого необходимо прервать сканирование"
Считывание прошло успешно
[28.10.2023 22:07:28] analyzeProcessCountChanging
Начинаем проверку числа процессов пользователя scorpion с интервалом 3 секунд
[28.10.2023 22:07:28] analyzeProcessCountChanging
Найдено 100 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:28] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 100, а максимальное значение 160
[28.10.2023 22:07:28]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:28] _divAndRound "1000" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:28]
Разделив делимое 1000 на делитель 160 нацело, получаем 6
[28.10.2023 22:07:28]
Разделим делимое 1000 на делитель 160 с остатком, получаем 40
[28.10.2023 22:07:28]
Разделим остаток 40, умноженный на 10, на делитель 160 нацело, получаем 2 — разряд десятых частного
[28.10.2023 22:07:28]
Округляя частное 6,2 до целых, разряд десятых отбрасываем, поскольку 2 < 5
[28.10.2023 22:07:28]
Добавим незаполненную часть из 4 ячеек в прогрессбар
[28.10.2023 22:07:28]
Добавим заполненную часть из 6 ячеек в начало прогрессбара.
[28.10.2023 22:07:28]
Итоговый прогрессбар: ******————
[28.10.2023 22:07:31] analyzeProcessCountChanging
Найдено 100 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:31] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 100, а максимальное значение 160
[28.10.2023 22:07:31]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:31] _divAndRound "1000" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:31]
Разделив делимое 1000 на делитель 160 нацело, получаем 6
[28.10.2023 22:07:31]
Разделим делимое 1000 на делитель 160 с остатком, получаем 40
[28.10.2023 22:07:31]
Разделим остаток 40, умноженный на 10, на делитель 160 нацело, получаем 2 — разряд десятых частного
[28.10.2023 22:07:31]
Округляя частное 6,2 до целых, разряд десятых отбрасываем, поскольку 2 < 5
[28.10.2023 22:07:31]
Добавим незаполненную часть из 4 ячеек в прогрессбар
[28.10.2023 22:07:31]
Добавим заполненную часть из 6 ячеек в начало прогрессбара.
[28.10.2023 22:07:31]
Итоговый прогрессбар: ******————
[28.10.2023 22:07:34] analyzeProcessCountChanging
Найдено 104 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:34] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 104, а максимальное значение 160
[28.10.2023 22:07:34]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:34] _divAndRound "1040" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:34]
Разделив делимое 1040 на делитель 160 нацело, получаем 6
[28.10.2023 22:07:34]
Разделим делимое 1040 на делитель 160 с остатком, получаем 80
[28.10.2023 22:07:34]
Разделим остаток 80, умноженный на 10, на делитель 160 нацело, получаем 5 — разряд десятых частного
[28.10.2023 22:07:34]
Округляя частное 6,5 до целых, увеличиваем целую часть на 1, поскольку 5 ≥ 5
[28.10.2023 22:07:34]
Добавим незаполненную часть из 3 ячеек в прогрессбар
[28.10.2023 22:07:34]
Добавим заполненную часть из 7 ячеек в начало прогрессбара.
[28.10.2023 22:07:34]
Итоговый прогрессбар: *******———
[28.10.2023 22:07:37] analyzeProcessCountChanging
Найдено 126 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:37] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 126, а максимальное значение 160
[28.10.2023 22:07:37]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:37] _divAndRound "1260" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:37]
Разделив делимое 1260 на делитель 160 нацело, получаем 7
[28.10.2023 22:07:37]
Разделим делимое 1260 на делитель 160 с остатком, получаем 140
[28.10.2023 22:07:37]
Разделим остаток 140, умноженный на 10, на делитель 160 нацело, получаем 8 — разряд десятых частного
[28.10.2023 22:07:37]
Округляя частное 7,8 до целых, увеличиваем целую часть на 1, поскольку 8 ≥ 5
[28.10.2023 22:07:37]
Добавим незаполненную часть из 2 ячеек в прогрессбар
[28.10.2023 22:07:37]
Добавим заполненную часть из 8 ячеек в начало прогрессбара.
[28.10.2023 22:07:37]
Итоговый прогрессбар: ********——
[28.10.2023 22:07:40] analyzeProcessCountChanging
Найдено 146 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:40] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 146, а максимальное значение 160
[28.10.2023 22:07:40]
Текущее значение меньше, чем максимальное. Умножим текущее значение на 10 и поделим на максимальное с учётом округления количества ячеек
[28.10.2023 22:07:40] _divAndRound "1460" "160"
Произведём деление до десятых с округлением до целых
[28.10.2023 22:07:40]
Разделив делимое 1460 на делитель 160 нацело, получаем 9
[28.10.2023 22:07:40]
Разделим делимое 1460 на делитель 160 с остатком, получаем 20
[28.10.2023 22:07:40]
Разделим остаток 20, умноженный на 10, на делитель 160 нацело, получаем 1 — разряд десятых частного
[28.10.2023 22:07:40]
Округляя частное 9,1 до целых, разряд десятых отбрасываем, поскольку 1 < 5
[28.10.2023 22:07:40]
Добавим незаполненную часть из 1 ячеек в прогрессбар
[28.10.2023 22:07:40]
Добавим заполненную часть из 9 ячеек в начало прогрессбара.
[28.10.2023 22:07:40]
Итоговый прогрессбар: *********—
[28.10.2023 22:07:43] analyzeProcessCountChanging
Найдено 166 процессов. Выведем требуемую информацию о них
[28.10.2023 22:07:43] getProgressBar
Получим прогрессбар длиной в 10 ячеек, имея текущее значение 166, а максимальное значение 160
[28.10.2023 22:07:43]
Текущее значение не меньше, чем максимальное. Значит, он будет заполнен полностью
[28.10.2023 22:07:43]
Текущее значение превышает максимальное. Добавим в прогрессбар символ '>', свидетельствующий об этом
[28.10.2023 22:07:43]
Добавим заполненную часть из 10 ячеек в начало прогрессбара.
[28.10.2023 22:07:43]
Итоговый прогрессбар: **********>
[28.10.2023 22:07:46] analyzeProcessCountChanging
Предел числа процессов (160) достигнут
[28.10.2023 22:07:46] ./main.sh "3" "3" "menu"
Действие "analyzeProcessCountChanging" завершено
[28.10.2023 22:07:46] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:07:46] _menuItems
Прочитаем и выведем 3 строк файла "menu"
[28.10.2023 22:07:46]
Выведено 3 пунктов меню
[28.10.2023 22:07:46] ./main.sh
Считаем символ для выбора пункта меню
[28.10.2023 22:07:46] readTillCorrectResult "_readNum" "пункт меню"
Будем запускать функцию считывания, пока она не завершится без ошибок
[28.10.2023 22:08:09]
Считан символ '3'. Проверим, является ли он номером одного из пунктов меню
[28.10.2023 22:08:09] isIntBetween "3" "пункт меню" "1" "3"
Проверим, является ли "3" числовым значением
[28.10.2023 22:08:09]
Проверим, лежит ли 3 между min=1 и max=3
[28.10.2023 22:08:09] _readNum
Сделаем пункт меню индексом (уменьшим на 1), чтобы обращаться по нему к массиву действий
[28.10.2023 22:08:09] readTillCorrectResult "_readNum" "пункт меню"
Считывание прошло успешно
[28.10.2023 22:08:09] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:08:09] ./main.sh "3" "3" "menu"
Начинаем выполнение действия "listNewProcesses"
[28.10.2023 22:08:09] listNewProcesses
Получаем общий список процессов
[28.10.2023 22:08:09] listNewProcesses
Выводим только те процессы из списка, которые появились после запуска скрипта (PID которого 216862)
[28.10.2023 22:08:09] ./main.sh "3" "3" "menu"
Действие "listNewProcesses" завершено
[28.10.2023 22:08:09] border
Выводим строчку с текущей датой и временем
[28.10.2023 22:08:09] ./main.sh
Выходим из основного цикла



