#### <font color = "#1D8571">О системе</font>
https://losst.pro/sbor-informatsii-o-sisteme-ubuntu
```bash
$ hostnamectl # версия ОС, ядра
$ cat /proc/cpuinfo
$ lsb_release -a
$ uname -a # версия ядра
$ df -h # место на дисках
$ cat /etc/os-release # версия ОС
$ uname -m # битность системы
```
##### <font color = "#1D8571">Полезное</font>
```bash
$ obsidian & # запуск программы в фоне
$ gio open my_pdf_book.pdf # открыть pdf документ
```
<h6>Hotkeys</h6>
```bash
$ ctrl + l # очистка экрана
# В утилите less
$ ctrl + f (+b) листать вниз и вверх постранично
$ ctrl + z # свернуть процесс
$ jobs # посмотреть свернутые процессы
$ fg %<номер программы> # (for graund) развернуть процесс
$ bg %<номер программы> # развернуть процесс в бекгрануд
$ ctrl + c # прервать процесс
```
<h4>Утилиты</h4>
**xxd** - вывод содержимого файлов в hex и bin форматах
```bash
$ xxd my_file.txt
$ xxd -с 1 -b my_file.txt 
# -b - выводит в двоичном формате
# -c 1 - вывод по одному символу
# -p - убрать справочную информацию
$ xxd -r -p file_in file_out # обратное преобразование
$ batcat # фналог cat, но с подсветкой синтаксиса
$ which batcat
$ sudo ln -s /usr/bin/batcat /usr/local/bin/bat #
$ mktemp # создает пустой файл со случайным именем в /tmp/
$ mktemp myfileXXX.txt # создает файл со случайными символами на месте 'XXX' в текущей директории
$ source ~/.bashrc # выполнить .bashrc в текущем сеансе оболочки
```
`sed` - потоковый редактор текста
Подробнее здесь: https://emulek.github.io/sed/index.html
<h4>Командная строка</h4>
<h6>Создание и удаление</h6>
```bash
$ true > file.txt # создает пустой файл
$ echo "hello world" > file.txt # создает файл и пишет строку 
$ touch {1..50} # создает 50 файлов с именами от 1 до 50
$ mkdir -p folder1/folder2/folder3 # создает вложенные директории
$ mkdir -p folder1/{folder2, folder3}/folder4 # второй способ
$ ls -R folder1 # рекурсивные вывод содержимого
$ tree folder1
$ echo ?.txt # выведет имена файлов только с 1 символом
$ # ? - это только один символ
$ touch user_{ivan, akex, petr}.txt #  создает 3 файлв с именами по шаблону
$ echo now is $(date) # вывод результата команды через $
$ rm *.txt # удаляет файлы по маске
```
<h6>Разное</h6>
```bash
$ du -sh /usr/bin # вывод размера директории /usr/bin
$ du -sh /usr/bin/* # вывод размера всех нескрытых файлов в /usr/bin
$ du -sh /usr/bin/* | sort -h | less # сортировка по размеру файлов
$ !du # команда du выполнится с предыдущими аргументами
$ cd - # Вернуться в предыдущую директорию
$ wc -l # считает количество строк переданных команде wc
$ export # выводит переменные окружения
$ export EDITOR=nano # установка переменной окружения
$ export "export EDITOR=nano" >> ~./bashrc # установить текстовый редактор по умолчанию
$ head -n10 file.txt # вывести 10 первых строк файла
$ tail -n10 file.txt # вывести 10 последних строк файла
$ cut -c 1-10 file.txt # выведет с 1-ого по 1-ый символы из каждой строчки файла
$ echo "123.456" | cut -d. -f1 # выведет 123, отрезает часть f по разделителю d
$ watch -n 1 date # запускает каждую секунду команду date
$ watch -g "df -h" # перезапускает команду df пока не изменится ее вывод
$ tr ":" "\" # заменяетодин символ на другой
$ dd if=/dev/urandom of=bigfile bs=64M count=17 iflag=fullblock # создать файл размером больше 1 гигабайта
$ ls -la && echo $? # $? возвращает код выполнение команды
```
<h6>История команд</h6>
```bash
$ history # выводит историю команд
$ history | less # листать историю команд
$ !25 # выполнить команду под номером 25
$ !! # повтороить предыдущую команду
$ 
```
<h6>Редактирование команд</h6>
```bash
$ ctrl + a # переход в начало строки
$ ctrl + e # переход в конец строки
$ ctrl + w # удаление по словам
```
<h6>Потоки ввода/вывода</h6>
">" :: Перенаправить поток вывода в файл. Файл будет перезаписан. 
"2>" :: Перенаправить поток ошибок в файл. Файл будет перезаписан. 
"&>" :: Перенаправить поток вывода и поток ошибок в файл. Файл будет перезаписан. 
">>" :: Перенаправить поток вывода в файл. Файл будет создан или дозаписан. 
"2>>" :: Перенаправить поток ошибок в файл. Файл будет создан дозаписан. 
"&>>" :: Перенаправить поток вывода и поток ошибок в файл. Файл будет создан или дозаписан. 
"|" :: Канал. Позволяет передать поток stdout одной команды в поток stdin другой команды.
```bash
$ echo hello world > 1.txt
$ echo new line >> 1.txt # дозаписать файл
$ cat 1.txt 2.txt > 3.txt # поместить содержимое двух файлов в третий
$ tac 3.txt # выводит файл в обратном порядке
$ ls nonexistent_file 2> 4.txt # перенаправить поток ошибок stderr в файл
$ ls nonexistet_file &> 4.txt # оба потока stdout и  stderr в файл
$ cat < 1.txt # передача в stdin
$ ls -la | tree output.txt # сохранит вывод ls в файл output.txt 
$ ls -ls | tee file.txt # выводит в stdout и в файл
```
<h6>Пользователи</h6>
```bash
$ whoami # выводи имя пользователя
$ cd # переход в домашнюю директорию пользователя

```
<h6>Статистика и информация</h6>
```bash
$ stat file.txt # вывод статистики
$ ls -l --time-style=full-iso file.txt # время выводится в полном формате
$ ls -l --time=atime file.txt # вывод времени доступа 
$ touch -a --date="tomorrow" test.txt # изменитьвремя обращения к файлу
$ touch -am --date="1990-06-01" test.txt # изменитьвремя обращения и время изменения файла
$ touch -t 202202031500 file.txt # изменить параметры Access и Modify у файла
```
<h6>Псевдонимы</h6>
```bash
$ alias l="ls -l" # создание alias. Сохраняется только в текущей сессии
# Для сохранения нужнодобавитьв .bashrc
```
<h6>Помощь</h6>
```bash
$ man ls # Получение справки по команде
$ ls --help
# ls --help | less # листать справку
```
<h6>Переменные окружения</h6>
```bash
$ env # вывод переменных окружения
$ echo $HOME # вывод значения переменной окружения
$ touch $USER.txt # создает файл с именем пользователя
$ export MY_VARIABLE=123 # создает переменную окружения в текущей сессии
$ echo "export MY_VARIABLE=123" >> .bashrc # 
$ TMP=123 env | less # установка переменной окружения в рамках одной команды
$ echo $PATH | tr ":" "\n" # Разбор значения переменной окружения `$PATH` путём разбития по символу двоеточия
$ export CDPATH=.:/cygdrive/c/projects # добавить путь для перехода командой cd
$ type ls # просмотр информации о команде ls
$ which ls # где находится команда ls
```
<h6>Файловая система Linux</h6>
```bash
$ bin -> usr/bin # ссылка на usr/bin
$ /boot # загрузчик
$ /dev # файлы устройств = устройства
$ /etc # конфигурация системных программ 
$ /home # домашние директории всех пользователей
$ lib -> usr/lib # библиотеки
$ /media # монтируются устройства
$ /mnt # монтируются устройства
$ /proc # файлы процессов
$ /root # директория суперпользователя
$ sbin -> usr/sbin # файлы программ, которые может запускать только root
$ /tmp # временные файлы
$ /usr # пользовательские программы
$ /var # частоизменяемые файлы
$ /sys # информация ядра о системе, устройствах и драйверах
$ /srv # файлы сервисов
```
<h6>Жесткие и (мягкие) символьные ссылки</h6>
Можно изменять данные по ссылкам.
При удалении файла символьная ссылка остается, но ссылается на пустое пространство. Но жесткая ссылка и данные остаются.
```bash
$ ln file.txt hard_link_to_file.txt # жесткая ссылкоа на file.txt
$ ln -s file.txt soft_link_to_file.txt # символьная ссылкоа на file.txt
```
<h6>Группы пользователей</h6>
```bash
$ io # показывает информацию пользователя
$ groups user_1 # вывести группы в которых состоит пользователь user_1
$ /etc/passwd # информация о пользователях
$ /etc/group # инфооормация о группах
$ sudo adduser new_user # создать нового пользователя
$ su - new_user # сменить пользователя
$ /etc/sudoers # пользователи с правами sudo
$ sudo groupadd friends # создать группу friends
$ sudo usermod -aG friends user_1 # добавить пользователя user_1 в группу friends
$ sudo passwd user_1 # изменить пароль пользователя user_1
$ sudo passwd # изменить пароль текущего пользователя
```
<h6>Права доступа</h6>
```bash
$ sudo chmod o-r hello # отнять права на чтение у others на файл hello
$ sudo chgrp my_group hello # сменить владеющую группу у файла hello
$ sudo deluser user my_group # удалить пользователя из группы
$ sudo chmod u+x hello # добавить валдельцу право на исполнение
$ sudo chmod g+rwx # добавить группе все права
$ sudo chown user my_file # изменить владельца файла
$ sudo chown user:group my_file # изменить владельца и группу файла
$ sudo chown :group my_file # изменить только группу файла
$ sudo chown user: my_file # изменить пользователя и группу файла (группа изменится на основную)
$ sudo chmod 777 file # права доступа по битовой маске
```
<h6>Права доступа к директориям. Пояснение:</h6>
<details>
<summary>Естественно, что по отношению к каталогам трактовка понятий «право на чтение», 
«право на запись» и «право на выполнение» несколько изменяется.</summary>
<p>Право на чтение по отношению к каталогам легко понять, если вспомнить, что каталог — это просто файл, содержащий список файлов в данном каталоге. Следовательно, если вы имеете право на чтение каталога, то вы можете просматривать его содержимое (этот самый список файлов в каталоге). Право на запись тоже понятно — имея такое право, вы сможете создавать и удалять файлы в этом каталоге, т. е. просто добавлять в каталог или удалять из него запись, содержащую имя какого-то файла и соответствующие ссылки. Право на выполнение в данном случае означает право переходить в этот каталог. Если вы, как владелец, хотите дать доступ другим пользователям на просмотр какого-то файла в своем каталоге, вы должны дать им право доступа в каталог, т. е. дать им «право на выполнение каталога». Более того, надо дать пользователю право на выполнение для всех каталогов, стоящих в дереве выше данного каталога. Поэтому в принципе для всех каталогов по умолчанию устанавливается право на выполнение как для владельца и группы, так и для всех остальных пользователей. И, уж если вы хотите закрыть доступ в каталог, то лишите всех пользователей (включая группу) права входить в этот каталог.</p>
 </details>
<h6>Архивирование - это не сжатие</h6>
```bash
$ du -sh original* # посмотреть размеры.
$ tar -cvf original.tar original # создать архив
$ tar -xvf original.tar #
$ tar -xcvf original.tar.gz original # создать сжатый архив
$ tar -xzvf original.tar.gz # разарзивировать
$ zip -r original.zip original # создать zip архив (сжатие)
$ unzip original.zip # распаковать архив
$ tar xvjf <.tar.bz2> # распаковать bz2 (опционально установить bzip2) 
```
<h6>Поиск</h6>
- $ which - показывает где лежит исполнимый файл
- $ locate - поиск файлов по предварительно создаваемому индексу
```bash
$ find # выводит все подпапки и файлы в виде списка
$ find . # тоже самое
$ find . -print # тоже самое (print - это что мы хотим сделать с найденными файлами)
$ find /var/log | less
$ find . -name "*.json" # найти все json файлы
$ find . -name "f*.json" # найти все json файлы с другой маской
$ find . -maxdepth 1 -name "*.json" # найти все json файлы только на первом уровне вложенности
$ find . -name "*first*" # поиск файлов и папок по маске
$ find . -type f -name "*first*" # поиск только файлов (d - только папок)
$ find . -type d -path ./second -prune -o -name "*.json" -print # искать json файлы исключая директорию ./second
$ find . -type d -path ./second -prune -o -type d -path ./first -o -name "*.json" -print # тоже самое, но исключается поиск и в ./first
# опция iname - независимо от регистра
# -o - параметр логическое ИЛИ
# -a - параметр логическое И
$ find . -type d -name "*second*" -prune -o -type d -name "*first*" -o -name "*.json" -print # из поиска исключить директории по шаблону
$ find . -type f -name "*.json" -o -type f -name "*.txt" # искать json или txt файлы
$ find . -type f -atime 0 # искать файлы по времени доступа за последние сутки
$ find . -type f -atime 1 # искать файлы по времени доступа за предпоследние сутки
$ find . -type f -mtime 0 # искать файлы по времени доступа за последние сутки
$ find . -type f -anewer file.txt # искать все файлы к которым доступ был получен позднее чем к файлу file.txt
$ find . -type f -cnewer file.txt # искать все файлы которые были изменены позднее чем файл file.txt
$ find . -type -f -size 140k # найти фалы размером 140k
$ find . -type -f -size +140k # найти фалы размером больше 140k
$ find . -type -f -size -140k # найти фалы размером меньше 140k
$ find . -type -f -size -150k -a -type f -size +130k # искать файлы в диапазоне 130 - 150k
$ find . -type f -exec du -sh {} \; # вывести размер каждого файла
$ find . -type f -exec du -sh {} \; | sort -h # вывести размер каждого файла и отсортировать
$ find . -type f -exec du -sh {} \; | sort -h | tail 3 # вывести размер каждого файла, отсортировать и вывести три последних
$ find . -type f -exec cat {} \; # вывести содержимое всех файлов
$ find . -type f -exec ls -la {} \; -exec cat {} \; -exec echo "---" \; # вывести содержимое файлов с информацией от ls и разделителем "---"
$ find . -type f -name "*.txt" -delete # удалить txt файлы
```
<h6>grep ripgrep</h6>
```bash
$ grep -rin --include="*.py" "charfield" .
# r - рекурсивно
# i - независимо от регистра
# n - вывести номра строк
# --include - в каких файлах искать
# "charfield" - собственно то, что искать
# . - искать в текущей директории
$ rg -i "charfield" # команда ripgrep - более понятный вывод
```
<h6>Разделение файлов</h6>
```bash
$ du -sh ./* | sort -h | tail -n10 # выводит топ 10 самых больших файлов
$ split -b 400M test.mov "test.mov." # разбивает файл на файлы размером 400Мб
$ cat test.mov.* > test_new.mov # собрать куски в один файл
$ md5sum test.mov test_new.mov # выдаст хеши файлов
$ cmp test.mov test_new.mov # сравнение файлов (если файлы одинаковы, то пустой вывод)
```
<h6>Установка программ, пакетный менеджер</h6>
```bash
$ sudo apt remove cowsay # удаление программы cowsay
$ sudo apt update # обновить информацию о пакетах
$ sudo apt purge cowsay # удалить программу и конфигурационные файлы
$ sudo apt upgrade # обновить все пакеты
$ sudo apt upgrade cowsay # обновить пакет cowsay
$ apt search cowsay # поиск пакетов
$ apt show cowsay # информация о пакете
```
<h6>Установка программ. Установка python из исходников</h6>
https://habr.com/ru/articles/673488/
```bash
$ wget https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tgz # скачать архив с ихсодниками
$ sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget libbz2-dev 
$ configure --enable-optimizations --prefix="$HOME/.python3.12"
$ sudo make -j2 && sudo make altinstall # j2 - исплоьзовать 2 ядра при сборке
$ echo "export PATH=$PATH:$HOME/.python3.12/bin" >> ~/.bashrc
$ sudo apt install <имя пакета> # установить или обновить пакет
```
<h6>htop</h6>
```bash
/ <имя процесса> - поиск процесса
k - выбор сигнала для процесса
```
<h6>Сигналы</h6>
- `SIGHUP`, номер `1`, как правило используется для того, чтобы уведомить процесс о необходимости перечитать файл конфигурации или обновить своё состояние иным образом
  
- `SIGKILL`, номер `9`, используется, чтобы убить процесс. У процесса нет возможности перехватить сигнал, чтобы обработать
   
- `SIGTERM`, номер `15`, используется, чтобы выйти из процесса мягко, процесс может перехватить сигнал и правильно завершить свою работу
```bash
$ kill -9 <ID процесса> # послать 9-ый сигнал
$ killall watch # убийство процесса по имени (killall входит в пакет psmisc)
$ pkill watch
$ kill -15 <ID процесса> # 
$ pkill -u user # убить все процессы запущенные пользователем user
```
<h6>wget</h6>
```bash
% wget google.com # скачать index.html в текущую директорию
```
<h6>zsh</h6>
```bash
$ sudo apt install -y zsh # установка
% echo $SHELL
```

<h6>Makefile</h6>
```make
.PHONY: hello
hello: 
	@echo "hello world"

# Start Django development server
.PHONY runserver:
runserver:
	@echo "run server"

.PHONY bye:
bye: hello
	@echo "bye-bye"
```
<h6>Задания на bash</h6>
```bash
$ mkdir -p {2020..2024}/{01..12}

```