Перейти к содержанию

Заметки

Заметки#

Диски#

Жесткие ссылки

Что это: Это прямые ссылки на один и тот же файл в файловой системе. Несколько имен могут указывать на один и тот же файл (один inode). Информация, которую хранят: Жесткая ссылка хранит inode файла — уникальный идентификатор файла в файловой системе, но не содержит путь к файлу.

Особенности: У всех жестких ссылок один и тот же inode, то есть это фактически один и тот же файл. Если исходный файл удален, остальные жесткие ссылки остаются рабочими, так как данные физически не удаляются, пока существует хотя бы одна жесткая ссылка. Работают только внутри одной файловой системы. Не могут ссылаться на каталоги (кроме системных ссылок типа . и ..).

Символические ссылки (symlinks)

Что это: Это ссылки, которые содержат путь к другому файлу или каталогу. Это фактически отдельный файл, который указывает на местоположение целевого файла. Информация, которую хранят: Символическая ссылка хранит путь к целевому файлу или директории.

Особенности: Если целевой файл удален, символическая ссылка становится «битой» и неработоспособной, так как она указывает на несуществующий путь. Символические ссылки могут указывать на файлы или каталоги. Работают между различными файловыми системами. Они легче по объему, поскольку содержат только путь к файлу, а не данные самого файла.

В файловой системе XFS иноды выделяются динамически, а вот в ext4 нет

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


Виртуальная файловая система — это файловая система, которая существует только в оперативной памяти и не хранит данные на диске, например /proc, также известная как procfs (процессная файловая система).

  • Не хранит данные на диске: Виртуальная файловая система отображает информацию, которая создаётся динамически при запросе и не сохраняется на постоянных носителях

  • Динамическое содержимое: Данные генерируются операционной системой в реальном времени. Например, содержимое файлов в /proc — это текущая информация о системе, процессах, памяти, конфигурациях и т.д., которая изменяется в зависимости от состояния системы.

Почему система виртуальная

  • Отражение состояния системы: Виртуальные файловые системы, такие как /proc, работают как интерфейс для чтения и управления текущим состоянием системы и процессами. Эти файлы не сохраняют данные, а лишь отображают их.
  • Экономия ресурсов: Так как информация хранится только в памяти, это позволяет быстро получать текущие данные, не записывая их на диск.

  • /sys: Динамическая информация о подключённых устройствах и драйверах.

  • /dev: Содержит устройства, создаваемые динамически

Динамическое создание: В большинстве современных систем устройства в /dev управляются с помощью udev (система управления устройствами), которая автоматически создаёт и удаляет файлы в зависимости от подключаемых устройств.

Нет данных на постоянных носителях: Данные о состоянии устройств хранятся в памяти, а сами файлы в /dev отображают текущие устройства системы.

Доступ через ядро: Когда обращаются к файлам в /dev, ядро перенаправляет запросы к соответствующим драйверам, позволяя операционной системе взаимодействовать с оборудованием и эмулированными устройствами.

SSH#

Файл ~/.ssh/known_hosts — это файл, который SSH использует для хранения информации о хостах (серверах), к которым вы ранее подключались. В этом файле хранятся "отпечатки" (fingerprints) публичных SSH-ключей серверов. Когда вы подключаетесь к серверу через SSH, клиент SSH проверяет, соответствует ли ключ сервера тому, который хранится в known_hosts.

Если ключ сервера изменился и не совпадает с тем, что хранится в known_hosts, SSH выдает предупреждение, чтобы предотвратить возможную атаку (например, "человек посередине").

Сигналы#

В Linux можно отправлять процессы различные сигналы, которые управляют их поведением. Эти сигналы — это механизмы межпроцессного взаимодействия (IPC), которые позволяют процессам реагировать на внешние события, такие как завершение или перезапуск.

  • kill -l - список всех сигналов в системе

Основные сигналы - SIGTERM (15) - Завершение процесса

kill -SIGTERM <pid>
# или
kill -15 <pid>
- SIGKILL (9) - Принудительное завершение процесса - SIGHUP (1) - "Повесить" процесс (например, если конфигурационные файлы изменились, и процесс нужно перезагрузить без остановки. Процесс может получить SIGHUP при отключении терминала, и если он не запрограммирован для обработки этого сигнала, он просто завершится) - SIGSTOP (19) - Остановка процесса. - SIGCONT (18) - Возобновление выполнения остановленного процесса.

Зомби и сироты#

Зомби-процесс — это завершившийся процесс, который всё ещё числится в таблице процессов, чтобы родитель мог получить его код завершения. Он не потребляет ресурсы, кроме записи в таблице процессов. Если таких процессов станет слишком много, это может помешать созданию новых, зомби не накапливаются, если родительский процесс правильно обрабатывает завершение дочерних.

Если родительский процесс корректно обрабатывает завершение своих дочерних процессов, зомби-процессы не накапливаются.

Если родительский процесс перестаёт функционировать, дочерние процессы (в том числе зомби) могут стать "сиротами" и будут переданы процессу init (PID 1), который автоматически собирает завершённые процессы и освобождает ресурсы.

Зомби-процессы нельзя "убить", так как они уже завершены. Однако можно решить проблему двумя способами:

  • Перезагрузка системы: Это удалит все зомби-процессы.
  • Убить родительский процесс: Если родительский процесс не обрабатывает завершение своих дочерних процессов, можно его завершить. Дочерние процессы будут переданы процессу init, который "соберёт" информацию о завершении и освободит зомби-процессы.

"Сирота" — это процесс, у которого завершился родительский процесс. В Linux системах, когда родительский процесс умирает до завершения своих дочерних процессов, эти дочерние процессы становятся "сиротами".

Что происходит с процессами-сиротами:

  • Переназначение процессу init: Как только процесс становится сиротой, он автоматически "усыновляется" процессом с PID 1 (обычно это init или его современный аналог systemd в современных дистрибутивах). Процесс init берёт на себя ответственность за сироту и следит за его завершением.

  • Корректное завершение: Когда процесс-сирота завершает свою работу, init собирает его статус завершения с помощью системного вызова wait() , предотвращая его превращение в зомби-процесс.

Отличие от зомби-процесса:

  • Сирота — это активный процесс, который просто потерял своего родителя.
  • Зомби — это завершённый процесс, чья запись остаётся в таблице процессов до тех пор, пока родитель не соберёт информацию о его завершении.

Сиротские процессы, в отличие от зомби, продолжают работать и не блокируют системные ресурсы, пока не завершат выполнение.

Состояния процессов#

  • R - Running - Процесс выполняется
  • S - Sleeping- Ожидание события (обычно ввода/вывода)
  • D - Uninterruptible Sleep - Процесс выполняет критический системный вызов (например, I/O)
  • T - Stopped- Процесс приостановлен (например, Ctrl+Z или SIGSTOP)
  • Z - Zombie- Завершен, но не убран родительским процессом
  • X - Dead - Мертвый процесс (редко)

Bash#

Команды в Linux выполняются слева направо, редиректы (>, >>, <) интерпретируются справа налево, потому что Bash сначала проверяет, куда нужно перенаправить вывод или откуда читать ввод, а потом выполняет саму команду.

echo "Hello" > file.txt
Здесь интерпретатор сначала создаёт или очищает файл file.txt (то есть обрабатывает часть > file.txt), а затем выполняет команду echo "Hello" и записывает результат в файл.
echo $(date)
Здесь сначала выполняется команда date (справа налево), а затем её результат подставляется в команду echo
echo `date`
Bash сначала выполнит команду date (внутри кавычек), затем передаст её результат команде echo.

ACL#

ACL (Access Control Lists) — позволяет более гибко управлять правами доступа к файлам в Linux. ACL позволяет назначать права для конкретных пользователей и групп, не меняя владельца файла или группу.

Для работы с ACL используются две основные команды:

  • setfacl - устанавливает ACL для файлов и каталогов
  • getfacl - показывает текущие ACL для файлов и каталогов

Синтаксис setfacl:

 setfacl [опции] [действие] [пользователь/группа]:[права] файл

Опции:

  • -m (modify) — изменить ACL.
  • -x (remove) — удалить ACL.
  • -b (remove all) — удалить все ACL.
  • -R (recursive) — применить рекурсивно ко всем файлам и подкаталогам.
  • -d (default) — установить ACL по умолчанию для новых файлов в каталоге.

Действия:

  • u:пользователь:права — установить права для пользователя.
  • g:группа:права — установить права для группы.
  • m::права — изменить маску (максимальные права для группы и других).

Права:

  • r — чтение.
  • w — запись.
  • x — выполнение (для каталогов — доступ).
  • X — выполнение, только если это каталог или файл уже имеет право на выполнение.
  • - — отсутствие прав.

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

# Дать пользователю prometheus права на чтение файла
sudo setfacl -m u:prometheus:r /etc/letsencrypt/live/prometheus.mcarov.pro/fullchain.pem
# Дать пользователю prometheus права на чтение и выполнение для каталога
sudo setfacl -m u:prometheus:rX /etc/letsencrypt/live/prometheus.mcarov.pro/
# Удалить ACL для пользователя prometheus
sudo setfacl -x u:prometheus /etc/letsencrypt/live/prometheus.mcarov.pro/fullchain.pem
# Удалить все ACL
sudo setfacl -b /etc/letsencrypt/live/prometheus.mcarov.pro/fullchain.pem
# Просмотр ACL
getfacl <file_name>

# Пример вывода:

# file: file.txt
# owner: user1
# group: group1
user::rw-
user:username:rwx
group::r--
mask::rwx
other::r--

Маска (mask) — это специальная запись ACL, которая ограничивает максимальные права доступа для всех записей ACL, кроме владельца файла и группы. Права владельца файла (owner) и группы (group), указанные в стандартных правах доступа (например, через chmod), не ограничиваются маской. Маска влияет только на дополнительные записи ACL, созданные для конкретных пользователей или групп.

Например, если маска установлена на r--, то даже если пользователю назначены права rwx, он сможет только читать файл.

# Задать маску 
setfacl -m m::r-- <file_name>

sudo setfacl -R -m u:prometheus:rX /etc/letsencrypt/

Разное#

Маска прав (umask) одна и та же для файлов и директорий, но результат применения маски отличается, поскольку начальные права у файлов и директорий разные (666 для файлов, 777 для директорий). То есть umask не различает файлы и директории, она применяется одинаково ко всем объектам, но итоговые права различаются из-за исходных прав.


top обновляется каждые 3 секунды


Что делает export?

export делает переменную окружения доступной для текущей оболочки и всех дочерних процессов. В данном случае она применяется к переменной PATH.

$, (), {}#

Символ $ используется для получения значения переменной. Когда пишешь $VAR, Bash подставляет значение переменной VAR.

name="Alice"
echo $name
Команды в круглых скобках () выполняются в подоболочке (subshell). Это означает, что изменения в окружении (например, переменные) внутри скобок не повлияют на основную оболочку.

Круглые скобки с $ $() используются для выполнения команды и подстановки её вывода.

current_date=$(date)
echo "Today is $current_date"

Фигурные скобки {} в Bash не меняют интерпретацию переменной, а только ограничивают её границы

# НЕВЕРНО, ! интерпретируется как часть имени переменной
name="Alice"
echo "Hello, $name!"
# ВЕРНО
name="Alice"
echo "Hello, ${name}!"

  • ${VAR:-default}: Когда нужно временно использовать значение по умолчанию, но не изменять переменную.

  • ${VAR:=default}: Когда нужно установить значение по умолчанию и сохранить его в переменной.

  • ${VAR:?error}: Когда нужно убедиться, что переменная определена, и завершить выполнение, если это не так.

  • ${VAR:+value}: Когда нужно выполнить действие только если переменная определена и не пуста.

Systemd#

Создание юнита#

  • в каталоге для хранения unit файлов cd /etc/systemd/system/ создаём файл с расширением .service для службы
  • bash sudo vi /etc/systemd/system/myservice.service
  • пишем unit файл
    [Unit]
    Description=Описание сервиса
    After=network.target  # Определяет, когда сервис должен запускаться (например, после сети)
    
    [Service]
    ExecStart=/path/to/your/executable_or_script  # Команда для запуска сервиса
    ExecStop=/path/to/stop/script (необязательно)  # Команда для остановки сервиса, если нужно
    ExecReload=/path/to/reload/script (необязательно)  # Команда для перезагрузки
    User=your_user  # Пользователь, от которого запустится сервис (если нужно)
    Group=your_group  # Группа (если нужно)
    Restart=always  # Политика перезапуска (может быть "on-failure", "always", "no")
    RestartSec=5  # Задержка перед перезапуском
    Environment="ENV_VAR=value"  # Можно задавать переменные окружения
    
    [Install]
    WantedBy=multi-user.target  # Указывает, что сервис должен запускаться в multi-user режиме (стандартный для большинства серверов)
    

    multi-user - многопользовательский текстовый режим

  • sudo systemctl daemon-reload - обновить конфигурацию systemd
  • sudo systemctl enable myservice.service - включает автозапуск юнита при перезагрузке системы
  • sudo systemctl start myservice.service - запустить юнит
  • sudo systemctl status myservice.service - статус юнита

Где же живут эти ваши юниты#

  • /etc/systemd/system/ - пользовательские юниты (имеют приоритет)
  • /usr/lib/systemd/system/ или /lib/systemd/system/ - юниты, которые создаются менеджерами пакетов при установке ПО
  • /run/systemd/system/ - временные юниты, созданные во время работы чего-то (например, контейнера)

Про wants и requires#

.wants

Используется для слабых зависимостей. Если основной юнит запущен, он попытается запустить все юниты, указанные в его .wants, но не завершит работу, если какой-то из них не удастся запустить.

Каталог .wants создается автоматически, если для юнита добавляют зависимость с WantedBy=.

.requires

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

Каталог .requires также создается при использовании директивы RequiredBy=, и его используют для критически необходимых зависимостей.