#import "@docs/bmstu:1.0.0":*
#import "@preview/tablex:0.0.8": tablex, rowspanx, colspanx, cellx
#show: student_work.with(
  caf_name: "Компьютерные системы и сети",
  faculty_name: "Информатика и системы управления",
  work_type: "лабораторной работе",  
  work_num: 4,
  study_field: "09.03.01 Информатика и вычислительная техника",
  discipline_name: "Операционные системы",
  theme: "Процессы",
  author: (group: "ИУ6-52Б", nwa: "<NAME>"),
  adviser: (nwa: "<NAME>"),
  city: "Москва",
  table_of_contents: true,
)
= Введение
== Цель работы

Получение теоретических и практических сведений об управлении
процессами, потоками и оперативной памятью в UNIX-подобных системах и в Linux в
частности.

== Задание
-	Открыть в текстовом браузере некую страницу и перевести его в фоновый режим
-	Запустить ещё два экземпляра текстового браузера в фоновом режиме
-	Найти процесс, максимально нагружающий процессор
-	Вывести список процессов текущего пользователя
-	«Убить» первый процесс браузера в котором открыта 1 страница
-	Вывести список всех процессов всех пользователей
-	Просмотреть список процессов постранично
-	Отобрать из вывода команды ps строку, соответствующую процессу «dbus-daemon», определить, где лежит её выполняемый файл и с какими параметрами он запущен
-	Записать в файл с именем, содержащим текущее время, строку «\-\-\-\-\-\-\-» и список процессов
-	Выполнить команду в фоновом режиме с отсрочкой запуска на 1 минуту. Продемонстрировать, что команда выполнилась именно через минуту.
-	Отобрать из одного из сформированных файлов строки, относящиеся к одному из процессов.
-	Вывести результаты работы произвольной команды в один файл, а сообщения об ошибках в другой. Продемонстрировать правильность работы.
-	Выполнить произвольную команду с ограничением использования процессорного времени 300 секунд и выводом результатов и сообщений об ошибках в один файл.
-	Настроить cron на выполнение команды ежедневно в заданное время. Продемонстрировать правильность работы.

= Выполнение
== Открыть в текстовом браузере некую страницу и перевести его в фоновый режим

Откроем в браузере `w3m` страницу `google.com`

#img(image("img/51.png", width:70%), [`ya.ru`])

Используя сочетания клавиш `Ctrl+z` переведем страницу в фоновый режим.

#img(image("img/52.png", width:70%), [Страница переведена в фоновый режим и отображается в списке процессов])

== Запустить ещё два экземпляра текстового браузера 
 
Откроем страницу `ya.ru` и переведем ее в фоновый режим.

#img(image("img/1.png", width:70%), [`ya.ru`])
#img(image("img/3.png", width:70%), [Страница переведена в фоновый режим и отображается в списке процессов])

Откроем страницу `cppreference.com` и переведем ее в фоновый режим.

#img(image("img/6.png", width:70%), [`cppreference.com`])
#img(image("img/8.png", width:70%), [Страница переведена в фоновый режим и отображается в списке процессов])

== Найти процесс, максимально нагружающий процессор

Для того, чтобы найти такой процесс выполним комманду ```sh top```:
#img(image("img/10.png", width:70%), [```sh top```])
Получается, что самым нагружающим процессом является `Xorg`.

== Вывести список процессов текущего пользователя

Удобнее комманды `top` есть комманда `ps`, если ее использовать с аргументом `a`, то получится вывести список процессов текущего пользователя.
#img(image("img/11.png", width:70%), [```sh ps a```])
#img(image("img/12.png", width:70%), [```sh ps a```])

== «Убить» первый процесс браузера в котором открыта 1 страница

Так как страница переведена в фоновый режим, то закрыть ее обычной коммандой `kill` передав аргументом `PID = 3228`, но можно добавить флаг `-9`, который означет принудительное завершение. 

#img(image("img/15.png", width:70%), [```sh kill -9 3228```])

Хоть и не сразу, но процесс завершился.

== Вывести список всех процессов всех пользователей

Для того, чтобы вывести список всех процессов всех пользователей используем ту же комманду ```sh ps``` с 3 аргументами: `axu`.

#img(image("img/19.png", width:70%), [```sh ps axu```])

== Просмотреть список процессов постранично

Воспользуемся коммандой `more` чтобы вывести тот же список, но постранично: ```sh ps axu|more```

#img(image("img/22.png", width:70%), [```sh ps axu|more```])

== Отобрать из вывода команды `ps` строку, соответствующую процессу `dbus-daemon`, определить, где лежит её выполняемый файл и с какими параметрами он запущен

Для того чтобы отобрать необходимую строку используем комманду `grep` совместно с коммандой `ps`:

#img(image("img/26.png", width:70%), [```sh ps axu|grep 'dbus-daemon'```])

== Записать в файл с именем, содержащим текущее время, строку «\-\-\-\-\-\-\-» и список процессов

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

Вот вся комманда:
```sh d="$(date)"; touch "$d"&&echo "dir:"&&ls -la|grep "$d" ;echo '-------'>>"$d"&&echo $(ps) >>"$d"&&echo "file:"&&cat "$d"```

Разберем по порядку:
- ```sh d="$(date)"``` берем текущее время в переменную ```sh $d```
- ```sh touch "$d"``` создаем файл с названием в виде текущего времени
- ```sh echo "dir:"``` пишем о том, что следующим сведением в консоль поступит полная директория файла
- ```sh ls -la|grep "$d" ``` ищем файл в текущей директории и выводим о нем информацию
- ```sh echo '-------' >> "$d"``` записываем в файл «\-\-\-\-\-\-\-»
- ```sh echo $(ps) >> "$d"``` Записываем в файл список текущих процессов
- ```sh echo "file:"``` Пишем что далее будет выведена информация записанная в файле
- ```sh cat "$d"``` читаем файл

#img(image("img/27.png", width:70%), [```sh d="$(date)";
 touch "$d"&&
 echo "dir:"&&
 ls -la|grep "$d" ;
 echo '-------'>>"$d"&&
 echo $(ps) >>"$d"&&
 echo "file:"&&
 cat "$d"
 ```])
 

 == Выполнить команду в фоновом режиме с отсрочкой запуска на 1 минуту. Продемонстрировать, что команда выполнилась именно через минуту.

```sh 
(sleep 60; ls -la > output.txt) & 
for i in {1..62}; do 
  echo "Текущее время: $(date '+%Y-%m-%d %H:%M:%S')"; 
  [ -f output.txt ] && cat output.txt || 
  echo "Файл output.txt не найден"; 
  sleep 1; 
done
```

Напишем еще одну составную комманду: 
- Отложим выполнение комманды ```sh ls -la > output.txt```, которая выводит информацию о текущей директории в файл `output.txt` на 1 минуту: ```sh (sleep 60; ls -la > output.txt)```
- Организуем цикл, который в течении 62 секунд будет выводить текущее время и найден ли файл (пока мы не записали ничего файла не будет). ```sh for i in {1..62}; do 
  echo "Текущее время: $(date '+%Y-%m-%d %H:%M:%S')"; 
  [ -f output.txt ] && cat output.txt || 
  echo "Файл output.txt не найден"; 
  sleep 1; 
done
```


#img(image("img/30.png", width:70%), [Начало выполнения комманды: минута еще не прошла])
#img(image("img/31.png", width:70%), [Комманда выполнилась, файл найден и выведен в терминал])

== Отобрать из одного из сформированных файлов строки, относящиеся к одному из процессов.

Чтобы отобрать строки, относящиеся к одному процессу напишем комманду ```sh grep``` и передадим в качечтве аргумента название процесса и название файла:

#img(image("img/33.png", width:70%), [```sh grep w3m 'Fri Sep 13 11:05:14 MSK 2024'```])

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

Для выполенния данной операции воспользуемся следующей коммандой: ```sh ls /usr /неправильный_путь > output.txt 2> error.txt```

Эта комманда выведет все, что есть в каталоге `/usr` в один файл и ошибку об отсутствии каталога `/неправильный_путь` в другой.

Дополнительно к комманде припишем чтение этих 2 файлов через отступ.

#img(image("img/34.png", width:70%), [```sh ls /usr /неправильный_путь > output.txt 2> error.txt;
cat output.txt &&
echo -e "\n\n" &&
cat error.txt
```])

== Выполнить произвольную команду с ограничением использования процессорного времени 300 секунд и выводом результатов и сообщений об ошибках в один файл.

Комманда ```sh find``` может занять достаточно много времени, поэтому ограничим ее выполение до 300с. Вывод напривим в файл `output.txt`, после чего прочитаем последние 10 строк из него:
```sh timeout 300s find / > output.txt 2>&1; tail output.txt```

#img(image("img/50.png", width:70%), [```sh timeout 300s find / > output.txt 2>&1; tail output.txt```])

== Настроить cron на выполнение команды ежедневно в заданное время. Продемонстрировать правильность работы.

Для начала откроем конфиг-файл ```sh cron```:

#img(image("img/35.png", width:70%), [```sh crontab -e```])

Пропишем сюда следующую строку: ```crontab 42 11 * * * /usr/bin/env echo "Hello World" » /output.txt```

- `42 11` Означает, что комманда выполнится в 11:42.
- `* * *` Означают, что комманда будет выполняться каждый день
- `/usr/bin/env` Путь к среде
- ```sh echo "Hello World" » /output.txt``` Комманда

#img(image("img/45.png", width:70%), [```sh crontab -e```])

Проверим все ли правильно записалось:

#img(image("img/46.png", width:70%), [```sh crontab -l```])

Проверим запущен ли демон ```sh cron```:
#img(image("img/47.png", width:70%), [```sh ps axu|grep cron```])

За минуту до назначенного времени запустим комманду, которая каждую секунду в течении 62 секунд проверяет наличие файла `output.txt` и его содержимое:

```sh for i in {1..62}; do 
  echo "Текущее время: $(date '+%Y-%m-%d %H:%M:%S')"; 
  [ -f output.txt ] && 
  cat output.txt || 
  echo "Файл output.txt не найден"; 
  sleep 1; 
done
```

#img(image("img/48.png", width:70%), [Комманда])
#img(image("img/49.png", width:70%), [Комманда])

В 11:42 файл появился и в него записалось Hello.
