Added about Linux

This commit is contained in:
Magnus Root 2026-04-06 11:02:36 +03:00
parent 920b20081b
commit 01f899d831
25 changed files with 4414 additions and 7 deletions

View file

@ -24,7 +24,7 @@
**Требования:** Go 1.21+ **Требования:** Go 1.21+
```bash ```bash
git clone https://gitverse.ru/magnusroot/rubric git clone https://github.com/user/rubric
cd rubric cd rubric
go build -o rubric . go build -o rubric .
``` ```
@ -32,7 +32,7 @@ go build -o rubric .
Или сразу установить глобально: Или сразу установить глобально:
```bash ```bash
go install gitverse.ru/magnusroot/rubric@latest go install github.com/user/rubric@latest
``` ```
--- ---
@ -218,4 +218,4 @@ var All = []Module{
Использует ANSI escape-коды. Работает в большинстве современных терминалов: iTerm2, Terminal.app, GNOME Terminal, Windows Terminal, tmux и других. Использует ANSI escape-коды. Работает в большинстве современных терминалов: iTerm2, Terminal.app, GNOME Terminal, Windows Terminal, tmux и других.
В средах без поддержки цвета (например, при перенаправлении вывода в файл) escape-коды будут видны как есть. При необходимости отключения цвета — установите переменную `NO_COLOR=1` перед запуском или реализуйте проверку `os.Getenv("NO_COLOR")` в `utils/display.go`. В средах без поддержки цвета (например, при перенаправлении вывода в файл) escape-коды будут видны как есть. При необходимости отключения цвета — установите переменную `NO_COLOR=1` перед запуском или реализуйте проверку `os.Getenv("NO_COLOR")` в `utils/display.go`.

View file

@ -20,7 +20,7 @@ type Book struct {
// All — список всех справочников // All — список всех справочников
var All = []Book{ var All = []Book{
GoBook, GoBook,
// LinuxBook — будет добавлен позже LinuxBook,
} }
// Find ищет книгу по ключу или алиасу // Find ищет книгу по ключу или алиасу

115
catalog/linuxbook.go Normal file
View file

@ -0,0 +1,115 @@
package catalog
import (
"bufio"
"fmt"
"rubric/modules/linuxmodules"
"rubric/utils"
"strconv"
"strings"
)
// LinuxBook — запись справочника Linux в главном меню
var LinuxBook = Book{
Key: "linux",
Aliases: []string{"l", "lnx"},
Title: "Справочник по GNU/Linux",
Description: "Основы GNU/Linux: файлы, процессы, сети, systemd, bash-скрипты и многое другое",
Run: runLinuxBook,
}
func runLinuxBook(scanner *bufio.Scanner) {
for {
showLinuxMenu()
input, ok := ReadLine(scanner)
if !ok {
return
}
if input == "" {
continue
}
if IsQuit(input) {
fmt.Printf("\n %s%sДо свидания!%s\n\n",
utils.ColorBold, utils.ColorCyan, utils.ColorReset)
return
}
if IsBack(input) {
return
}
// По номеру
if n, err := strconv.Atoi(input); err == nil {
if n >= 1 && n <= len(linuxmodules.All) {
linuxmodules.All[n-1].Run()
waitLinuxBack(scanner)
continue
}
fmt.Printf("\n %s%sНомер %d вне диапазона (1%d)%s\n",
utils.ColorBold, utils.ColorRed, n, len(linuxmodules.All), utils.ColorReset)
continue
}
// По ключу
if m, ok := linuxmodules.Find(input); ok {
m.Run()
waitLinuxBack(scanner)
continue
}
fmt.Printf("\n %s%sНе понял '%s'. Номер, ключ раздела, b — назад.%s\n",
utils.ColorBold, utils.ColorRed, input, utils.ColorReset)
}
}
func showLinuxMenu() {
utils.Header("Справочник GNU/Linux")
fmt.Printf(" %s%sРазделы:%s\n\n",
utils.ColorBold, utils.ColorWhite, utils.ColorReset)
for i, m := range linuxmodules.All {
aliases := ""
if len(m.Aliases) > 0 {
aliases = fmt.Sprintf("%s [%s]%s",
utils.ColorDim, strings.Join(m.Aliases, ", "), utils.ColorReset)
}
fmt.Printf(" %s%s %2d.%s %s%-12s%s %s%-30s%s%s\n",
utils.ColorBold, utils.ColorCyan, i+1, utils.ColorReset,
utils.ColorYellow+utils.ColorBold, m.Key, utils.ColorReset,
utils.ColorWhite, m.Title, utils.ColorReset,
aliases,
)
fmt.Printf(" %s%s%s\n\n",
utils.ColorDim, m.Description, utils.ColorReset)
}
fmt.Printf(" %s%sРаздел (номер / ключ / b — главное меню / q — выход):%s ",
utils.ColorBold, utils.ColorGreen, utils.ColorReset)
}
type linuxBackSignal struct{}
func waitLinuxBack(scanner *bufio.Scanner) {
fmt.Printf("\n %s%s[Enter — назад в меню Linux, b — главное меню]%s ",
utils.ColorDim, utils.ColorCyan, utils.ColorReset)
if scanner.Scan() {
if IsBack(strings.TrimSpace(scanner.Text())) {
panic(linuxBackSignal{})
}
}
}
func init() {
orig := LinuxBook.Run
LinuxBook.Run = func(scanner *bufio.Scanner) {
defer func() {
if r := recover(); r != nil {
if _, ok := r.(linuxBackSignal); !ok {
panic(r)
}
}
}()
orig(scanner)
}
}

16
main.go
View file

@ -7,11 +7,12 @@ import (
"os" "os"
"rubric/catalog" "rubric/catalog"
"rubric/modules/gomodules" "rubric/modules/gomodules"
"rubric/modules/linuxmodules"
"rubric/utils" "rubric/utils"
) )
func main() { func main() {
book := flag.String("book", "", "открыть справочник напрямую (например: -book go)") book := flag.String("book", "", "открыть справочник напрямую (go, linux)")
topic := flag.String("topic", "", "открыть раздел (используется вместе с -book)") topic := flag.String("topic", "", "открыть раздел (используется вместе с -book)")
list := flag.Bool("list", false, "список всех справочников и разделов") list := flag.Bool("list", false, "список всех справочников и разделов")
help := flag.Bool("help", false, "справка по использованию") help := flag.Bool("help", false, "справка по использованию")
@ -29,7 +30,7 @@ func main() {
return return
} }
// -book go -topic basics // -book X -topic Y
if *book != "" && *topic != "" { if *book != "" && *topic != "" {
switch *book { switch *book {
case "go", "g", "golang": case "go", "g", "golang":
@ -41,6 +42,15 @@ func main() {
os.Exit(1) os.Exit(1)
} }
m.Run() m.Run()
case "linux", "l", "lnx":
m, ok := linuxmodules.Find(*topic)
if !ok {
fmt.Printf("\n %s%sРаздел '%s' не найден в справочнике Linux.%s\n",
utils.ColorBold, utils.ColorRed, *topic, utils.ColorReset)
linuxmodules.ListModules()
os.Exit(1)
}
m.Run()
default: default:
fmt.Printf("\n %s%sСправочник '%s' не найден.%s\n", fmt.Printf("\n %s%sСправочник '%s' не найден.%s\n",
utils.ColorBold, utils.ColorRed, *book, utils.ColorReset) utils.ColorBold, utils.ColorRed, *book, utils.ColorReset)
@ -50,7 +60,7 @@ func main() {
return return
} }
// -book go // -book X
if *book != "" { if *book != "" {
b, ok := catalog.Find(*book) b, ok := catalog.Find(*book)
if !ok { if !ok {

View file

@ -0,0 +1,189 @@
package linuxmodules
import (
"rubric/utils"
)
var BackupModule = Module{
Key: "backup",
Aliases: []string{"bk", "tar", "бэкап"},
Title: "Резервное копирование",
Description: "Темы 3840: tar, инкрементальные бэкапы, rsync, VDO",
Run: showBackup,
}
func showBackup() {
utils.Header("Linux — Резервное копирование")
// ─── 38. tar ──────────────────────────────────────────────────
utils.Section("38. Создание бэкапов с tar")
utils.Println("tar — основной инструмент архивирования в Linux.")
utils.Println(utils.ColorBold + "\nОсновные флаги tar:" + utils.ColorReset)
utils.Code(`c create (создать архив)
x extract (извлечь)
t list (показать содержимое)
v verbose (подробный вывод)
f file (имя файла архива)
z gzip (сжатие gzip, .tar.gz / .tgz)
j bzip2 (сжатие bzip2, .tar.bz2)
J xz (сжатие xz, .tar.xz)
p preserve permissions (сохранить права)
C change directory (распаковать в указанную папку)`)
utils.Println(utils.ColorBold + "Создание архива:" + utils.ColorReset)
utils.Code(`# Создать архив:
tar -cvf archive.tar /path/to/dir # без сжатия
tar -czvf archive.tar.gz /etc/ # с gzip
tar -cjvf archive.tar.bz2 /var/www/ # с bzip2
tar -cJvf archive.tar.xz /home/alice/ # с xz (медленнее, лучше)
# Создать с меткой даты:
tar -czvf backup_$(date +%Y%m%d_%H%M).tar.gz /etc/
# Исключить директории:
tar -czvf backup.tar.gz /home/ \
--exclude=/home/.cache \
--exclude='/home/*/.local'
# Архивировать только изменённые файлы:
tar -czvf backup.tar.gz --newer "2024-01-01" /home/`)
utils.Println(utils.ColorBold + "Извлечение архива:" + utils.ColorReset)
utils.Code(`# Извлечь в текущую директорию:
tar -xvf archive.tar
tar -xzvf archive.tar.gz
# Извлечь в указанную директорию:
tar -xzvf archive.tar.gz -C /tmp/restore/
# Извлечь только конкретные файлы:
tar -xzvf archive.tar.gz etc/nginx/nginx.conf
# Просмотр содержимого без распаковки:
tar -tzvf archive.tar.gz
tar -tzvf archive.tar.gz | grep nginx`)
utils.Println(utils.ColorBold + "rsync — синхронизация файлов:" + utils.ColorReset)
utils.Code(`# Базовый синтаксис: rsync [опции] источник назначение
# Опции:
-a архивный режим (-rlptgoD: рекурсия, права, время...)
-v verbose
-z сжатие при передаче
-P прогресс + продолжение
-n dry-run (симуляция без изменений)
--delete удалять файлы которых нет в источнике
-e ssh использовать SSH
# Локальная синхронизация:
rsync -av /source/ /dest/ # / после source содержимое (без самой папки)
rsync -av /source /dest/ # без / копирует саму папку
# По сети через SSH:
rsync -avzP /home/alice/ user@server:/backup/alice/
rsync -avzP user@server:/data/ /local/backup/
# Зеркало (с удалением лишнего):
rsync -av --delete /source/ /mirror/
# Бэкап с сохранением удалённых файлов:
rsync -av --backup --backup-dir=/backup/old-$(date +%Y%m%d) \
--delete /source/ /mirror/`)
// ─── 39. Инкрементальные бэкапы ───────────────────────────────
utils.Section("39. Инкрементальные бэкапы с tar")
utils.Println("Инкрементальный бэкап — сохраняет только изменения с момента последнего бэкапа.")
utils.Code(`# tar поддерживает инкрементальные бэкапы через snapshot-файл.
# Snapshot хранит список файлов и время последнего изменения.
# Полный бэкап (level 0):
tar -czvf backup_full_$(date +%Y%m%d).tar.gz \
--listed-incremental=/var/backup/snapshot.snar \
/home/
# Инкрементальный бэкап (только изменения):
tar -czvf backup_incr_$(date +%Y%m%d_%H%M).tar.gz \
--listed-incremental=/var/backup/snapshot.snar \
/home/
# Восстановление: сначала полный, затем все инкрементальные по порядку:
tar -xzvf backup_full_20240101.tar.gz \
--listed-incremental=/dev/null -C /restore/
tar -xzvf backup_incr_20240102.tar.gz \
--listed-incremental=/dev/null -C /restore/
# Просмотр инкрементального архива:
tar -tzvf backup_incr.tar.gz --listed-incremental=/dev/null`)
utils.Println(utils.ColorBold + "Скрипт автоматического бэкапа:" + utils.ColorReset)
utils.Code(`#!/bin/bash
set -euo pipefail
BACKUP_DIR="/backup"
SOURCE="/home /etc /var/www"
SNAPSHOT="/var/backup/snapshot.snar"
DATE=$(date +%Y%m%d_%H%M)
LOG="/var/log/backup.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }
log "Начало бэкапа"
# Полный бэкап по воскресеньям, инкрементальный остальные дни:
if [ "$(date +%u)" -eq 7 ]; then
cp "$SNAPSHOT" "${SNAPSHOT}.prev" 2>/dev/null || true
ARCHIVE="$BACKUP_DIR/full_$DATE.tar.gz"
tar -czvf "$ARCHIVE" --listed-incremental="$SNAPSHOT" $SOURCE
log "Полный бэкап: $ARCHIVE"
else
ARCHIVE="$BACKUP_DIR/incr_$DATE.tar.gz"
tar -czvf "$ARCHIVE" --listed-incremental="$SNAPSHOT" $SOURCE
log "Инкрементальный бэкап: $ARCHIVE"
fi
# Удалить старые бэкапы (оставить за 30 дней):
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete
log "Старые бэкапы очищены. Готово."`)
// ─── 40. VDO ──────────────────────────────────────────────────
utils.Section("40. Дедупликация с VDO (Virtual Data Optimizer)")
utils.Println("VDO — технология RHEL для дедупликации и сжатия данных на блочном уровне.")
utils.Println("Уменьшает занимаемое место на диске без изменения работы приложений.")
utils.Code(`# VDO доступен в RHEL/CentOS. Установка:
dnf install vdo kmod-kvdo
# Создать VDO-устройство поверх блочного (/dev/sdb):
vdo create --name=vdo_data \
--device=/dev/sdb \
--vdoLogicalSize=100G # виртуальный размер (больше физического)
# Посмотреть VDO-устройства:
vdo list
vdo status --name=vdo_data
# Создать ФС на VDO:
mkfs.ext4 -E nodiscard /dev/mapper/vdo_data
mount /dev/mapper/vdo_data /mnt/data
# Статистика экономии:
vdostats --human-readable
# Показывает: физический размер / использовано / коэффициент сжатия
# VDO в /etc/fstab:
/dev/mapper/vdo_data /mnt/data ext4 defaults,x-systemd.requires=vdo.service 0 2
# Запустить/остановить:
vdo start --name=vdo_data
vdo stop --name=vdo_data
# Удалить VDO:
vdo remove --name=vdo_data --force`)
utils.Note("VDO хорошо работает для виртуализации, контейнеров и бэкапов — там много одинаковых данных.")
utils.Note("LVM 2.3+ поддерживает VDO напрямую через lvcreate --type vdo.")
utils.Footer()
}

View file

@ -0,0 +1,238 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var BashModule = Module{
Key: "bash",
Aliases: []string{"sh", "shell", "баш"},
Title: "Bash: основы и переменные",
Description: "Темы 1213: bash-completion, alias, type, переменные окружения",
Run: showBash,
}
func showBash() {
utils.Header("Linux — Bash: основы и переменные")
// ─── 12. Bash #1 ──────────────────────────────────────────────
utils.Section("12. Bash #1: bash-completion, alias, type")
utils.Println(utils.ColorBold + "bash-completion — автодополнение Tab:" + utils.ColorReset)
utils.Code(`Tab дополнить команду / путь / аргумент
Tab Tab показать все варианты
# Примеры:
git che<Tab> git checkout
ls /etc/sy<Tab> ls /etc/systemd/
ssh us<Tab> ssh user@hostname (из ~/.ssh/config)
systemctl st<Tab> systemctl start/status/stop
# Установить расширенный bash-completion:
# Debian/Ubuntu: apt install bash-completion
# RHEL/Fedora: dnf install bash-completion
# Активировать в ~/.bashrc:
[ -f /etc/bash_completion ] && . /etc/bash_completion`)
utils.Println(utils.ColorBold + "alias — псевдонимы команд:" + utils.ColorReset)
utils.Code(`# Посмотреть все алиасы:
alias
# Создать алиас (действует до конца сессии):
alias ll='ls -la'
alias la='ls -la'
alias ..='cd ..'
alias ...='cd ../..'
alias grep='grep --color=auto'
alias rm='rm -i' # защита от случайного удаления
alias df='df -h'
alias free='free -h'
alias update='sudo apt update && sudo apt upgrade'
# Использование алиаса:
ll /etc
# Удалить алиас:
unalias ll
# Посмотреть что делает алиас:
alias ll`)
utils.Println(utils.ColorBold + "Постоянные алиасы — добавить в ~/.bashrc:" + utils.ColorReset)
utils.Code(`# ~/.bashrc
alias ll='ls -la --color=auto'
alias la='ls -la'
alias l='ls -CF'
alias ..='cd ..'
alias grep='grep --color=auto'
alias h='history'
alias c='clear'
# Применить без перезапуска терминала:
source ~/.bashrc
# или:
. ~/.bashrc`)
utils.Println(utils.ColorBold + "type — определить тип команды:" + utils.ColorReset)
utils.Code(`type ls
# ls is aliased to 'ls --color=auto'
type cd
# cd is a shell builtin
type python3
# python3 is /usr/bin/python3
type ll
# ll is aliased to 'ls -la'
type if
# if is a shell keyword
# Опции:
type -a ls # все варианты (алиас + файл)
type -t ls # только тип: alias/builtin/file/keyword`)
utils.Println(utils.ColorBold + "which и whereis:" + utils.ColorReset)
utils.Command("which python3", "полный путь к исполняемому файлу")
utils.Command("which -a python", "все версии python в PATH")
utils.Command("whereis nginx", "бинарник, исходники, man-страница")
utils.Command("command -v git", "путь или алиас (POSIX-совместимо)")
fmt.Println()
utils.Println(utils.ColorBold + "Работа с историей команд:" + utils.ColorReset)
utils.Command("history", "полная история")
utils.Command("history 20", "последние 20 команд")
utils.Command("!42", "выполнить команду №42")
utils.Command("!!", "повторить последнюю команду")
utils.Command("!ls", "последняя команда начинающаяся с ls")
utils.Command("Ctrl+R", "интерактивный поиск по истории")
utils.Command("history -c", "очистить историю")
fmt.Println()
utils.Code(`# Файл истории: ~/.bash_history
# Управление историей через переменные в ~/.bashrc:
HISTSIZE=10000 # размер в памяти
HISTFILESIZE=20000 # размер файла
HISTCONTROL=ignoredups # не сохранять дубли
HISTCONTROL=ignorespace # команды с пробелом впереди не сохраняются
# Временные метки в истории:
HISTTIMEFORMAT="%F %T "`)
// ─── 13. Bash #2: переменные ──────────────────────────────────
utils.Section("13. Bash #2: переменные")
utils.Println(utils.ColorBold + "Переменные оболочки:" + utils.ColorReset)
utils.Code(`# Создать переменную:
name="Alice" # без пробелов вокруг =
count=42
PATH_BACKUP=$PATH # использовать значение другой переменной
# Использовать переменную ($ перед именем):
echo $name # Alice
echo "Привет, $name!" # Привет, Alice!
echo "Привет, ${name}!" # фигурные скобки явное обозначение
# Удалить переменную:
unset name`)
utils.Println(utils.ColorBold + "Переменные окружения (Environment Variables):" + utils.ColorReset)
utils.Code(`# Переменные оболочки vs переменные окружения:
# - переменная оболочки видна только в текущем shell
# - переменная окружения (export) передаётся дочерним процессам
# Экспортировать:
export name="Alice"
export PATH="$PATH:/opt/myapp/bin"
# Или сразу:
export count=42
# Посмотреть все переменные окружения:
env
printenv
printenv PATH # конкретная переменная
echo $PATH # то же`)
utils.Println(utils.ColorBold + "Важные системные переменные:" + utils.ColorReset)
utils.Code(`PATH список директорий для поиска команд (: разделитель)
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin
HOME домашняя директория (~) /home/alice
USER имя пользователя alice
LOGNAME логин пользователя alice
SHELL оболочка пользователя /bin/bash
TERM тип терминала xterm-256color
LANG язык/локаль en_US.UTF-8
LC_ALL переопределить все локали
PWD текущая директория /home/alice/docs
OLDPWD предыдущая директория
PS1 приглашение командной строки
PS2 вторичное приглашение (>)
EDITOR редактор по умолчанию vim
VISUAL визуальный редактор vim
PAGER пагинатор less
HISTSIZE размер истории в памяти
RANDOM случайное число 0-32767`)
utils.Println(utils.ColorBold + "Специальные переменные bash:" + utils.ColorReset)
utils.Code(`$0 имя скрипта / оболочки
$1..$9 позиционные параметры (аргументы скрипта)
$@ все аргументы как отдельные строки
$* все аргументы как одна строка
$# количество аргументов
$? код возврата последней команды (0 = успех)
$$ PID текущего процесса
$! PID последнего фонового процесса
$_ последний аргумент предыдущей команды`)
utils.Code(`# Примеры:
echo $? # 0 если последняя команда успешна
ls /nonexistent
echo $? # 2 (или другой ненулевой) ошибка
echo $$ # PID bash
echo $RANDOM # случайное число`)
utils.Println(utils.ColorBold + "Работа со строками переменных:" + utils.ColorReset)
utils.Code(`name="alice"
${name} alice
${name^} Alice (первая буква заглавная)
${name^^} ALICE (все заглавные)
${name,,} alice (все строчные)
str="hello world"
${#str} 11 (длина строки)
${str:0:5} hello (подстрока с 0, длиной 5)
${str:6} world (с позиции 6 до конца)
path="/home/user/file.txt"
${path##*/} file.txt (удалить до последнего /)
${path%/*} /home/user (удалить от последнего /)
${path%.*} /home/user/file (удалить расширение)
${path##*.} txt (только расширение)
# Значения по умолчанию:
${var:-default} default если var не задана или пустая
${var:=default} присвоить и вернуть default если пустая
${var:?ошибка} вывести ошибку если пустая`)
utils.Println(utils.ColorBold + "Настройка ~/.bashrc и ~/.bash_profile:" + utils.ColorReset)
utils.Code(`~/.bashrc выполняется при каждом запуске интерактивного bash
~/.bash_profile выполняется при входе в систему (login shell)
~/.profile POSIX-совместимый аналог .bash_profile
~/.bash_logout выполняется при выходе
# Типичный ~/.bashrc:
export PATH="$HOME/.local/bin:$PATH"
export EDITOR=vim
alias ll='ls -la'
alias ..='cd ..'
# ~/.bash_profile обычно вызывает ~/.bashrc:
[[ -f ~/.bashrc ]] && . ~/.bashrc
# Применить изменения без перезапуска:
source ~/.bashrc`)
utils.Footer()
}

View file

@ -0,0 +1,223 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var BootModule = Module{
Key: "boot",
Aliases: []string{"bo", "systemd", "grub", "загрузка"},
Title: "Загрузка системы и systemd",
Description: "Темы 3335, 41: GRUB, systemd, юниты, управление сервисами",
Run: showBoot,
}
func showBoot() {
utils.Header("Linux — Загрузка системы и systemd")
// ─── 33. GRUB ─────────────────────────────────────────────────
utils.Section("33. Загрузчик GRUB")
utils.Println("Процесс загрузки Linux:")
utils.Code(`BIOS/UEFI MBR/GPT GRUB Ядро (vmlinuz) initrd/initramfs /sbin/init (systemd) Сервисы Пользователь
BIOS/UEFI инициализация железа, поиск загрузочного устройства
MBR/GPT первый сектор диска, указывает где GRUB
GRUB загрузчик, выбор ядра/ОС
vmlinuz сжатое ядро Linux
initramfs временная корневая ФС в памяти (для монтирования /)
systemd PID 1, запускает все сервисы`)
utils.Println(utils.ColorBold + "GRUB — конфигурация:" + utils.ColorReset)
utils.Code(`# Основные файлы:
/boot/grub/grub.cfg итоговая конфигурация (не редактировать!)
/etc/grub.d/ скрипты генерации конфига
/etc/default/grub настройки
# Редактировать настройки:
sudo nano /etc/default/grub
# Ключевые параметры /etc/default/grub:
GRUB_DEFAULT=0 # пункт меню по умолчанию (0 = первый)
GRUB_TIMEOUT=5 # таймаут выбора (сек)
GRUB_CMDLINE_LINUX="" # параметры ядра для всех записей
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" # для обычной загрузки
# Применить изменения:
sudo update-grub # Debian/Ubuntu
sudo grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL/Fedora`)
utils.Println(utils.ColorBold + "GRUB — установка и восстановление:" + utils.ColorReset)
utils.Code(`# Установить GRUB на диск:
sudo grub-install /dev/sda # Debian/Ubuntu
sudo grub2-install /dev/sda # RHEL/Fedora
# Восстановление GRUB через LiveCD:
mount /dev/sda2 /mnt # корневой раздел
mount /dev/sda1 /mnt/boot/efi # EFI раздел (UEFI)
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
chroot /mnt
grub-install /dev/sda
update-grub
exit; reboot`)
utils.Println(utils.ColorBold + "Параметры ядра при загрузке:" + utils.ColorReset)
utils.Code(`# Нажать 'e' в меню GRUB для редактирования записи.
# Найти строку linux/linuxefi и добавить параметры в конец:
ro quiet splash стандартная загрузка
rw single однопользовательский режим (recovery)
init=/bin/bash минимальный shell (без systemd)
nomodeset без KMS (проблемы с видео)
rd.break остановить в initramfs (RHEL)
systemd.unit=rescue.target аварийный режим`)
// ─── 34. systemd ──────────────────────────────────────────────
utils.Section("34. Система инициализации — systemd")
utils.Println("systemd — PID 1. Управляет всеми сервисами, монтированием, логами.")
fmt.Println()
utils.Println(utils.ColorBold + "Юниты (Units):" + utils.ColorReset)
utils.Code(`Юнит объект управления systemd.
Типы юнитов:
.service сервис (nginx.service, sshd.service)
.socket сокет (активация по запросу)
.target группа юнитов (graphical.target = GUI)
.timer планировщик (альтернатива cron)
.mount точка монтирования
.path отслеживание файлов/директорий
.slice группа процессов (управление ресурсами)
# Расположение юнитов:
/lib/systemd/system/ системные (из пакетов)
/etc/systemd/system/ пользовательские (переопределение)
/run/systemd/system/ временные (runtime)`)
// ─── 35. Управление сервисами ─────────────────────────────────
utils.Section("35. Системный менеджер systemd: управление сервисами")
utils.Println(utils.ColorBold + "systemctl — основные команды:" + utils.ColorReset)
utils.Command("systemctl status nginx", "статус сервиса")
utils.Command("systemctl start nginx", "запустить")
utils.Command("systemctl stop nginx", "остановить")
utils.Command("systemctl restart nginx", "перезапустить")
utils.Command("systemctl reload nginx", "перечитать конфигурацию")
utils.Command("systemctl enable nginx", "включить автозапуск")
utils.Command("systemctl disable nginx", "выключить автозапуск")
utils.Command("systemctl enable --now nginx", "включить и сразу запустить")
utils.Command("systemctl disable --now nginx", "выключить и остановить")
utils.Command("systemctl is-active nginx", "активен? (active/inactive)")
utils.Command("systemctl is-enabled nginx", "в автозапуске? (enabled/disabled)")
utils.Command("systemctl is-failed nginx", "завершился с ошибкой?")
fmt.Println()
utils.Command("systemctl list-units", "список всех активных юнитов")
utils.Command("systemctl list-units --type=service", "только сервисы")
utils.Command("systemctl list-units --failed", "упавшие юниты")
utils.Command("systemctl list-unit-files", "все юниты и их состояние")
utils.Command("systemctl daemon-reload", "перечитать файлы юнитов (после изменений)")
fmt.Println()
utils.Println(utils.ColorBold + "Таргеты (targets) — уровни запуска:" + utils.ColorReset)
utils.Code(`poweroff.target выключение (runlevel 0)
rescue.target однопользовательский (runlevel 1)
multi-user.target многопользовательский без GUI (runlevel 3)
graphical.target с GUI (runlevel 5)
reboot.target перезагрузка (runlevel 6)
# Текущий таргет:
systemctl get-default
# Изменить таргет по умолчанию:
systemctl set-default multi-user.target
# Переключиться немедленно:
systemctl isolate multi-user.target
# Выключение и перезагрузка:
systemctl poweroff
systemctl reboot
systemctl suspend
systemctl hibernate`)
utils.Println(utils.ColorBold + "journalctl — просмотр логов systemd:" + utils.ColorReset)
utils.Command("journalctl", "все логи")
utils.Command("journalctl -u nginx", "логи конкретного сервиса")
utils.Command("journalctl -f", "следить в реальном времени")
utils.Command("journalctl -f -u nginx", "следить за nginx")
utils.Command("journalctl -n 50", "последние 50 строк")
utils.Command("journalctl --since '2024-01-15 10:00'", "с определённого времени")
utils.Command("journalctl --since '1 hour ago'", "за последний час")
utils.Command("journalctl -p err", "только ошибки (emerg alert crit err warning notice info debug)")
utils.Command("journalctl -b", "с момента последней загрузки")
utils.Command("journalctl -b -1", "предыдущая загрузка")
utils.Command("journalctl --disk-usage", "объём логов на диске")
utils.Command("journalctl --vacuum-size=100M", "оставить только 100МБ логов")
// ─── 41. Systemd юниты ────────────────────────────────────────
utils.Section("41. Создание systemd юнитов")
utils.Println(utils.ColorBold + "Структура .service файла:" + utils.ColorReset)
utils.Code(`# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
Documentation=https://example.com
After=network.target # запустить после сети
Requires=postgresql.service # обязательная зависимость
Wants=redis.service # желательная зависимость
[Service]
Type=simple # forking, oneshot, notify, idle
User=myapp # от какого пользователя
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp --config /etc/myapp.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure # always, on-failure, on-abnormal
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=NODE_ENV=production
EnvironmentFile=/etc/myapp/env
# Ограничения:
MemoryMax=512M
CPUQuota=50%
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target`)
utils.Code(`# Применить новый юнит:
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
# Переопределить параметры (без редактирования оригинала):
sudo systemctl edit nginx # создаёт /etc/systemd/system/nginx.service.d/override.conf`)
utils.Println(utils.ColorBold + "Timer юнит (альтернатива cron):" + utils.ColorReset)
utils.Code(`# /etc/systemd/system/backup.timer
[Unit]
Description=Ежедневный бэкап
[Timer]
OnCalendar=*-*-* 02:00:00 # каждый день в 02:00
OnCalendar=Mon *-*-* 03:00 # каждый понедельник в 03:00
OnBootSec=15min # через 15 мин после загрузки
OnUnitActiveSec=1h # каждый час после последнего запуска
Persistent=true # запустить если пропустили время
[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Скрипт бэкапа
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh`)
utils.Footer()
}

View file

@ -0,0 +1,211 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var DisksModule = Module{
Key: "disks",
Aliases: []string{"d", "lvm", "raid", "диски"},
Title: "Диски, файловые системы, LVM и RAID",
Description: "Темы 2226: разделы, mount, LVM, программный RAID",
Run: showDisks,
}
func showDisks() {
utils.Header("Linux — Диски, файловые системы, LVM и RAID")
// ─── 22. Работа с дисками ─────────────────────────────────────
utils.Section("22. Работа с дисками и разделами")
utils.Println(utils.ColorBold + "Именование устройств:" + utils.ColorReset)
utils.Code(`/dev/sda первый SATA/SCSI диск
/dev/sdb второй диск
/dev/sda1 первый раздел первого диска
/dev/sda2 второй раздел первого диска
/dev/nvme0n1 первый NVMe диск
/dev/nvme0n1p1 первый раздел NVMe диска
/dev/vda виртуальный диск (KVM/QEMU)
/dev/xvda диск Xen
/dev/loop0 loop-устройство (ISO-образ)`)
utils.Println(utils.ColorBold + "Просмотр дисков и разделов:" + utils.ColorReset)
utils.Command("lsblk", "дерево блочных устройств")
utils.Command("lsblk -f", "с типом ФС и UUID")
utils.Command("lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE", "выбрать столбцы")
utils.Command("fdisk -l", "все диски и разделы (root)")
utils.Command("fdisk -l /dev/sda", "разделы диска sda")
utils.Command("parted -l", "таблицы разделов (GPT и MBR)")
utils.Command("blkid", "UUID и типы ФС всех устройств")
utils.Command("blkid /dev/sda1", "UUID конкретного раздела")
fmt.Println()
utils.Println(utils.ColorBold + "Разбивка диска (fdisk):" + utils.ColorReset)
utils.Code(`sudo fdisk /dev/sdb # интерактивная работа с разделами
Команды fdisk:
p показать таблицу разделов
n новый раздел
d удалить раздел
t изменить тип раздела
l список типов разделов
w записать изменения (опасно!)
q выйти без сохранения
# Для GPT-дисков и дисков > 2ТБ используйте parted или gdisk`)
utils.Println(utils.ColorBold + "Создание файловой системы (mkfs):" + utils.ColorReset)
utils.Command("mkfs.ext4 /dev/sdb1", "создать ext4")
utils.Command("mkfs.xfs /dev/sdb1", "создать xfs")
utils.Command("mkfs.ext4 -L data /dev/sdb1", "с меткой 'data'")
utils.Command("mkswap /dev/sdb2", "создать swap")
utils.Command("swapon /dev/sdb2", "активировать swap")
utils.Command("swapon -s", "показать активные swap")
utils.Command("swapoff /dev/sdb2", "отключить swap")
fmt.Println()
utils.Println(utils.ColorBold + "Проверка и восстановление ФС:" + utils.ColorReset)
utils.Command("fsck /dev/sdb1", "проверить ФС (только при размонтированной!)")
utils.Command("fsck -n /dev/sdb1", "только проверить, не исправлять")
utils.Command("e2fsck -f /dev/sdb1", "принудительная проверка ext2/3/4")
utils.Command("xfs_repair /dev/sdb1", "восстановление XFS")
utils.Println(utils.ColorBold + "Использование диска:" + utils.ColorReset)
utils.Command("df -h", "занятое и свободное место на ФС")
utils.Command("df -hT", "с типом ФС")
utils.Command("du -sh /var/log", "размер директории")
utils.Command("du -sh /*", "размер каждой директории в корне")
utils.Command("du -sh * | sort -h", "отсортировать по размеру")
utils.Command("ncdu /var", "интерактивный анализ (нужно установить)")
// ─── 2324. Файловые системы и монтирование ───────────────────
utils.Section("2324. Файловые системы и монтирование")
utils.Println(utils.ColorBold + "mount — монтирование:" + utils.ColorReset)
utils.Command("mount", "список всех смонтированных ФС")
utils.Command("mount /dev/sdb1 /mnt/data", "монтировать раздел")
utils.Command("mount -t ext4 /dev/sdb1 /mnt", "указать тип ФС")
utils.Command("mount -o ro /dev/sdb1 /mnt", "только чтение")
utils.Command("mount -o remount,rw /", "перемонтировать с правами записи")
utils.Command("mount UUID=abc123 /mnt/data", "монтировать по UUID")
utils.Command("mount -a", "смонтировать всё из /etc/fstab")
utils.Command("umount /mnt/data", "размонтировать")
utils.Command("umount -l /mnt/data", "ленивое размонтирование (когда занято)")
utils.Command("lsof /mnt/data", "кто использует раздел (если umount отказывает)")
fmt.Println()
utils.Println(utils.ColorBold + "/etc/fstab — автомонтирование при старте:" + utils.ColorReset)
utils.Code(`# Формат: устройство точкаонтирования тип опции dump fsck
UUID=abc123 /mnt/data ext4 defaults 0 2
/dev/sdb1 /mnt/data xfs defaults 0 0
//server/share /mnt/smb cifs credentials=/etc/samba.creds 0 0
tmpfs /tmp tmpfs defaults,size=2G 0 0
# Опции монтирования:
defaults rw, suid, exec, auto, nouser, async
ro только чтение
rw чтение и запись
noexec запрет запуска файлов
nosuid игнорировать SUID/SGID биты
noatime не обновлять atime (быстрее)
auto монтировать при mount -a
noauto не монтировать автоматически
# Столбцы dump и fsck:
# dump: 0 = не бэкапить, 1 = бэкапить
# fsck: 0 = не проверять, 1 = / (первый), 2 = остальные`)
utils.Note("Всегда используйте UUID вместо /dev/sdb1 в fstab — имена устройств могут меняться после перезагрузки.")
// ─── 25. LVM ──────────────────────────────────────────────────
utils.Section("25. Управление логическими томами — LVM")
utils.Println("LVM позволяет гибко управлять дисковым пространством:")
utils.Println("объединять несколько дисков, изменять размер томов без перезагрузки.")
fmt.Println()
utils.Code(`Структура LVM:
PV (Physical Volume) физический диск или раздел (/dev/sdb)
VG (Volume Group) группа PV, единый пул пространства
LV (Logical Volume) логический том из VG (аналог раздела)
PV: /dev/sdb /dev/sdc
VG: vg_data (объединённое пространство)
LV: /dev/vg_data/lv_web /dev/vg_data/lv_db`)
utils.Println(utils.ColorBold + "Создание LVM:" + utils.ColorReset)
utils.Code(`# 1. Создать Physical Volume:
pvcreate /dev/sdb /dev/sdc
pvs # показать PV
pvdisplay # подробно
# 2. Создать Volume Group:
vgcreate vg_data /dev/sdb /dev/sdc
vgs # показать VG
vgdisplay vg_data
# 3. Создать Logical Volume:
lvcreate -L 20G -n lv_web vg_data # 20 ГБ
lvcreate -l 100%FREE -n lv_db vg_data # всё свободное
lvs # показать LV
lvdisplay /dev/vg_data/lv_web
# 4. Создать ФС и смонтировать:
mkfs.ext4 /dev/vg_data/lv_web
mount /dev/vg_data/lv_web /var/www`)
utils.Println(utils.ColorBold + "Расширение LV:" + utils.ColorReset)
utils.Code(`# Расширить LV на 10 ГБ:
lvextend -L +10G /dev/vg_data/lv_web
# Расширить ФС (ext4):
resize2fs /dev/vg_data/lv_web
# Одной командой (ext4):
lvextend -L +10G -r /dev/vg_data/lv_web # -r = resize ФС
# Для XFS (только увеличение):
xfs_growfs /var/www`)
utils.Println(utils.ColorBold + "Добавить диск в VG:" + utils.ColorReset)
utils.Code(`pvcreate /dev/sdd
vgextend vg_data /dev/sdd`)
// ─── 26. Программный RAID ─────────────────────────────────────
utils.Section("26. Программный RAID — MD (mdadm)")
utils.Println("RAID — избыточный массив для надёжности и/или производительности.")
fmt.Println()
utils.Code(`Уровни RAID:
RAID 0 страйпинг (производительность), без избыточности
RAID 1 зеркало (надёжность), нужно 2 диска, использует 50%
RAID 5 страйп + чётность, нужно 3+ дисков, теряем 1 диск
RAID 6 двойная чётность, нужно 4+ дисков, теряем 2 диска
RAID 10 зеркало + страйп, нужно 4 диска, теряем до N/2`)
utils.Println(utils.ColorBold + "mdadm — управление программным RAID:" + utils.ColorReset)
utils.Code(`# Создать RAID 1 из двух дисков:
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc
# Создать RAID 5:
mdadm --create /dev/md0 --level=5 --raid-devices=3 \
/dev/sdb /dev/sdc /dev/sdd
# Состояние массива:
cat /proc/mdstat # текущее состояние
mdadm --detail /dev/md0 # подробная информация
# Сохранить конфигурацию:
mdadm --detail --scan >> /etc/mdadm/mdadm.conf
# Добавить запасной диск:
mdadm /dev/md0 --add /dev/sde
# Удалить диск из массива:
mdadm /dev/md0 --fail /dev/sdb
mdadm /dev/md0 --remove /dev/sdb
# Остановить массив:
mdadm --stop /dev/md0`)
utils.Footer()
}

View file

@ -0,0 +1,266 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var FilesModule = Module{
Key: "files",
Aliases: []string{"f", "dirs", "файлы"},
Title: "Файлы и директории",
Description: "Темы 0610: пути, cp/mv/rm, ссылки, чтение файлов, nano и vi",
Run: showFiles,
}
func showFiles() {
utils.Header("Linux — Файлы и директории")
// ─── 06. Пути и директории ────────────────────────────────────
utils.Section("06. Пути и директории")
utils.Println(utils.ColorBold + "Абсолютный и относительный пути:" + utils.ColorReset)
utils.Code(`Абсолютный: начинается с /
/home/user/documents/file.txt
Относительный: относительно текущей директории
documents/file.txt (из /home/user)
../другой/файл (.. родительская директория)
./скрипт.sh (. текущая директория)`)
utils.Println(utils.ColorBold + "Специальные обозначения:" + utils.ColorReset)
utils.Code(`. текущая директория
.. родительская директория
~ домашняя директория текущего пользователя
~/ то же самое, используется в путях: ~/docs
- предыдущая директория (cd -)`)
utils.Println(utils.ColorBold + "Навигация:" + utils.ColorReset)
utils.Command("pwd", "показать текущую директорию (Print Working Directory)")
utils.Command("cd /etc", "перейти в /etc (абсолютный путь)")
utils.Command("cd docs", "перейти в docs (относительный)")
utils.Command("cd ..", "перейти в родительскую директорию")
utils.Command("cd ~", "перейти домой")
utils.Command("cd -", "вернуться в предыдущую директорию")
utils.Command("cd", "то же что cd ~")
fmt.Println()
utils.Println(utils.ColorBold + "Просмотр содержимого:" + utils.ColorReset)
utils.Command("ls", "список файлов текущей директории")
utils.Command("ls -l", "длинный формат (права, владелец, размер, дата)")
utils.Command("ls -a", "все файлы включая скрытые (начинаются с .)")
utils.Command("ls -la", "длинный формат + скрытые")
utils.Command("ls -lh", "размер в читаемом виде (K, M, G)")
utils.Command("ls -lt", "сортировка по времени (новые сверху)")
utils.Command("ls -ltr", "по времени в обратном порядке")
utils.Command("ls -R", "рекурсивно (все вложенные)")
utils.Command("ls /etc/*.conf", "glob-паттерн: все .conf в /etc")
fmt.Println()
utils.Code(`# Пример вывода ls -l:
drwxr-xr-x 2 alice users 4096 Jan 15 10:30 docs
-rw-r--r-- 1 alice users 512 Jan 14 09:00 file.txt
lrwxrwxrwx 1 alice users 7 Jan 13 12:00 link -> file.txt
имя файла
дата изменения
размер (байты)
группа
владелец
количество жёстких ссылок
тип и права доступа`)
utils.Println(utils.ColorBold + "Создание директорий:" + utils.ColorReset)
utils.Command("mkdir mydir", "создать директорию")
utils.Command("mkdir -p a/b/c", "создать вложенные директории")
utils.Command("mkdir -p project/{src,docs,tests}", "создать несколько сразу")
utils.Command("rmdir mydir", "удалить пустую директорию")
// ─── 07. Создание и копирование файлов ───────────────────────
utils.Section("07. Создание и копирование файлов")
utils.Println(utils.ColorBold + "Создание файлов:" + utils.ColorReset)
utils.Command("touch file.txt", "создать пустой файл / обновить время доступа")
utils.Command("touch file{1..5}.txt", "создать file1.txt … file5.txt")
utils.Command("> file.txt", "создать пустой файл / очистить существующий")
utils.Command("echo 'текст' > file.txt", "записать текст в файл")
utils.Command("echo 'текст' >> file.txt", "добавить текст в конец файла")
fmt.Println()
utils.Println(utils.ColorBold + "Копирование (cp):" + utils.ColorReset)
utils.Command("cp src dst", "скопировать файл")
utils.Command("cp -r src/ dst/", "скопировать директорию рекурсивно")
utils.Command("cp -v src dst", "показать что копируется (-v = verbose)")
utils.Command("cp -i src dst", "спросить при перезаписи (-i = interactive)")
utils.Command("cp -p src dst", "сохранить права/метаданные (-p = preserve)")
utils.Command("cp -a src/ dst/", "архивный режим: -r + -p + символические ссылки")
utils.Command("cp *.txt /tmp/", "копировать все .txt в /tmp")
fmt.Println()
utils.Note("cp -r не сохраняет права и время по умолчанию. Для резервного копирования используйте cp -a.")
// ─── 08. Перемещение, удаление, ссылки ───────────────────────
utils.Section("08. Перемещение, переименование, удаление. Ссылки")
utils.Println(utils.ColorBold + "Перемещение и переименование (mv):" + utils.ColorReset)
utils.Command("mv old.txt new.txt", "переименовать файл")
utils.Command("mv file.txt /tmp/", "переместить в /tmp")
utils.Command("mv -v src dst", "подробный вывод")
utils.Command("mv -i src dst", "спросить при перезаписи")
utils.Command("mv -n src dst", "не перезаписывать существующий")
fmt.Println()
utils.Println(utils.ColorBold + "Удаление (rm):" + utils.ColorReset)
utils.Command("rm file.txt", "удалить файл")
utils.Command("rm -r dir/", "удалить директорию рекурсивно")
utils.Command("rm -rf dir/", "принудительно, без подтверждений")
utils.Command("rm -i file.txt", "спросить перед удалением")
utils.Command("rm -v file.txt", "показать что удаляется")
fmt.Println()
utils.Note("rm -rf удаляет безвозвратно. Нет корзины. Будьте внимательны!")
utils.Code(`# Защита: никогда не делайте:
rm -rf / # удалит всю систему
rm -rf ./ # удалит текущую директорию
# Безопаснее: перенести в /tmp, потом удалить
mv dangerous_dir /tmp/ && rm -rf /tmp/dangerous_dir`)
utils.Println(utils.ColorBold + "Жёсткие ссылки (hard links):" + utils.ColorReset)
utils.Code(`Жёсткая ссылка ещё одно имя для того же inode.
ln file.txt hardlink.txt # создать жёсткую ссылку
Особенности:
- указывает на те же данные на диске
- не отличить от оригинала командой ls
- удаление одного имени не удаляет данные
(данные удаляются когда счётчик ссылок = 0)
- нельзя создать на директорию
- нельзя создать на другой раздел/диске`)
utils.Println(utils.ColorBold + "Символические ссылки (soft links / symlinks):" + utils.ColorReset)
utils.Code(`Символическая ссылка файл, содержащий путь к цели.
ln -s /etc/nginx/nginx.conf nginx.conf # создать симлинк
ln -s /path/to/dir mylink # симлинк на директорию
ls -la nginx.conf
# lrwxrwxrwx 1 user group 20 Jan nginx.conf -> /etc/nginx/nginx.conf
Особенности:
- показывается как l в ls -la
- может указывать на директории
- может быть "битым" (цель удалена)
- можно создать между разными разделами
- readlink nginx.conf показать куда указывает`)
utils.Command("stat file.txt", "показать подробную информацию о файле (inode, ссылки)")
utils.Command("ls -i file.txt", "показать номер inode")
// ─── 09. Чтение текстовых файлов ─────────────────────────────
utils.Section("09. Чтение текстовых файлов")
utils.Command("cat file.txt", "вывести весь файл")
utils.Command("cat -n file.txt", "с номерами строк")
utils.Command("cat -A file.txt", "показать спецсимволы ($ в конце строк)")
utils.Command("cat f1 f2 > merged", "объединить файлы")
fmt.Println()
utils.Command("less file.txt", "постраничный просмотр (рекомендуется для больших файлов)")
utils.Command("more file.txt", "постраничный просмотр (только вперёд)")
fmt.Println()
utils.Code(`Навигация в less:
Space / PgDn следующая страница
b / PgUp предыдущая страница
g / G начало / конец файла
/паттерн поиск вперёд
?паттерн поиск назад
n / N следующее / предыдущее совпадение
q выход`)
utils.Command("head file.txt", "первые 10 строк")
utils.Command("head -n 20 file.txt", "первые 20 строк")
utils.Command("head -c 100 file.txt", "первые 100 байт")
utils.Command("tail file.txt", "последние 10 строк")
utils.Command("tail -n 30 file.txt", "последние 30 строк")
utils.Command("tail -f /var/log/syslog", "следить за файлом в реальном времени")
utils.Command("tail -F /var/log/nginx/access.log", "следить, даже если файл пересоздаётся")
fmt.Println()
utils.Command("grep 'текст' file.txt", "поиск строк содержащих 'текст'")
utils.Command("grep -i 'TEXT' file.txt", "без учёта регистра")
utils.Command("grep -r 'текст' /etc/", "рекурсивный поиск в директории")
utils.Command("grep -n 'текст' file.txt", "с номерами строк")
utils.Command("grep -v 'текст' file.txt", "строки НЕ содержащие 'текст'")
utils.Command("grep -c 'текст' file.txt", "количество совпадений")
utils.Command("grep -l 'текст' *.conf", "только имена файлов с совпадениями")
fmt.Println()
utils.Command("wc file.txt", "количество строк, слов, байт")
utils.Command("wc -l file.txt", "только строки")
utils.Command("wc -w file.txt", "только слова")
utils.Command("sort file.txt", "сортировать строки")
utils.Command("sort -r file.txt", "в обратном порядке")
utils.Command("sort -n file.txt", "числовая сортировка")
utils.Command("sort -u file.txt", "убрать дубли (unique)")
utils.Command("uniq file.txt", "убрать соседние одинаковые строки")
utils.Command("cut -d: -f1 /etc/passwd", "вырезать первое поле (разделитель :)")
utils.Command("cut -d, -f2,4 data.csv", "поля 2 и 4 из CSV")
utils.Command("tr 'a-z' 'A-Z' < file.txt", "заменить символы (нижний → верхний регистр)")
utils.Command("diff file1 file2", "сравнить два файла")
utils.Command("diff -u file1 file2", "unified-формат (как git diff)")
// ─── 10. Текстовые редакторы ──────────────────────────────────
utils.Section("10. Текстовые редакторы: nano и vi/vim")
utils.Println(utils.ColorBold + "nano — простой редактор:" + utils.ColorReset)
utils.Command("nano file.txt", "открыть файл в nano")
utils.Code(`Основные сочетания клавиш в nano:
Ctrl+O сохранить (Write Out)
Ctrl+X выйти
Ctrl+K вырезать строку
Ctrl+U вставить
Ctrl+W поиск
Ctrl+\ замена
Ctrl+G справка
Alt+U отменить (undo)`)
utils.Println(utils.ColorBold + "vi / vim — мощный редактор:" + utils.ColorReset)
utils.Command("vi file.txt", "открыть в vi")
utils.Command("vim file.txt", "открыть в vim (улучшенный vi)")
fmt.Println()
utils.Code(`Режимы vim:
Нормальный (Normal) навигация, команды. По умолчанию.
Вставки (Insert) ввод текста. Нажать i.
Командный (Command) команды (:). Нажать :
Визуальный (Visual) выделение. Нажать v.
Переключение:
i режим вставки перед курсором
a режим вставки после курсора
o новая строка ниже, режим вставки
O новая строка выше, режим вставки
Esc вернуться в нормальный режим`)
utils.Code(`Навигация (нормальный режим):
h j k l
w / b следующее / предыдущее слово
0 / $ начало / конец строки
gg / G начало / конец файла
:n перейти на строку n
Ctrl+F/B вперёд / назад на страницу
Редактирование:
dd удалить строку
yy скопировать строку (yank)
p вставить после курсора
P вставить перед курсором
u отменить (undo)
Ctrl+R повторить (redo)
/текст поиск вперёд
n / N следующее / предыдущее совпадение
:%s/old/new/g заменить все вхождения
Сохранение и выход:
:w сохранить
:q выйти
:wq или ZZ сохранить и выйти
:q! выйти без сохранения
:wq! принудительно сохранить и выйти`)
utils.Note("Если застряли в vi — нажмите Esc несколько раз, затем :q! для выхода без сохранения.")
utils.Note("vimtutor — встроенный интерактивный учебник по vim (30 мин). Запустите в терминале.")
utils.Footer()
}

View file

@ -0,0 +1,161 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var IntroModule = Module{
Key: "intro",
Aliases: []string{"i", "os", "начало"},
Title: "Введение. ОС и GNU/Linux",
Description: "Темы 01, 04, 05: операционные системы, файловые системы, терминал",
Run: showIntro,
}
func showIntro() {
utils.Header("Linux — Введение. ОС и GNU/Linux")
// ─── 01. Операционные системы и GNU/Linux ─────────────────────
utils.Section("01. Операционные системы и GNU/Linux")
utils.Println("Операционная система (ОС) — программа, управляющая аппаратурой и")
utils.Println("предоставляющая среду для работы прикладных программ.")
fmt.Println()
utils.Println(utils.ColorBold + "Ключевые понятия:" + utils.ColorReset)
utils.Code(`Ядро (kernel) центральная часть ОС, управляет памятью,
процессами, устройствами.
Userspace пространство пользователя, где работают
обычные программы.
Дистрибутив ядро Linux + набор программ + система управления
пакетами (Debian, Ubuntu, RHEL, Fedora, Arch...).`)
utils.Println(utils.ColorBold + "История:" + utils.ColorReset)
utils.Code(`1969 AT&T Bell Labs: UNIX (Ричи, Томпсон)
1983 Ричард Столлман: проект GNU (свободное ПО)
1991 Линус Торвальдс: ядро Linux (v0.01)
= GNU/Linux: ядро Linux + утилиты GNU
POSIX стандарт совместимости UNIX-подобных систем`)
utils.Println(utils.ColorBold + "GNU/Linux vs другие ОС:" + utils.ColorReset)
utils.Code(`Linux Windows macOS
Открытый код Закрытый Частично открытый
Бесплатно Платный Платный (только на Mac)
Пакетный менеджер Магазин/exe App Store/Homebrew
Множество дистро Одна система Одна система
Сильный CLI GUI-ориентирован CLI через zsh/bash`)
utils.Note("Серверы: >90% работают на Linux. Android — ядро Linux. Суперкомпьютеры: 100% Linux.")
utils.Note("RHEL (Red Hat Enterprise Linux) — коммерческий дистрибутив; RHCSA — его сертификация.")
// ─── 04. О файловых системах ──────────────────────────────────
utils.Section("04. О файловых системах")
utils.Println("Файловая система (ФС) — способ организации хранения данных на диске.")
fmt.Println()
utils.Println(utils.ColorBold + "Популярные файловые системы Linux:" + utils.ColorReset)
utils.Code(`ext4 стандарт для большинства дистрибутивов,
журналирование, поддержка файлов до 16 ТБ
xfs высокая производительность, RHEL по умолчанию,
хорошо для больших файлов
btrfs Copy-on-Write, снапшоты, сжатие
vfat совместимость с Windows (флешки, EFI-раздел)
ntfs чтение/запись Windows-разделов (ntfs-3g)
tmpfs виртуальная ФС в оперативной памяти (/tmp, /run)
proc виртуальная ФС, информация о процессах (/proc)
sysfs виртуальная ФС, информация об устройствах (/sys)`)
utils.Println(utils.ColorBold + "Структура файловой системы Linux (FHS):" + utils.ColorReset)
utils.Code(`/ корень, начало всего дерева
bin/ основные бинарные файлы (ls, cp, mv...)
sbin/ системные бинарники (root: fdisk, mount...)
etc/ конфигурационные файлы
home/ домашние директории пользователей
root/ домашняя директория root
var/ изменяемые данные (логи, кэш, БД)
tmp/ временные файлы (очищается при перезагрузке)
usr/ пользовательские программы и данные
bin/ программы пользователя
lib/ библиотеки
share/ разделяемые данные
lib/ системные библиотеки
dev/ файлы устройств (sda, tty, null...)
proc/ виртуальная ФС: инфо о процессах и ядре
sys/ виртуальная ФС: инфо об устройствах
run/ данные запущенных процессов (PID-файлы)
boot/ загрузчик, ядро (vmlinuz, initrd)
mnt/ точки монтирования (временные)
media/ автомонтирование съёмных носителей`)
utils.Note("В Linux всё — файл: устройства, сокеты, каналы, процессы.")
utils.Note("Нет буквы диска (C:, D:). Всё монтируется в единое дерево с корнем /")
utils.Println(utils.ColorBold + "Типы файлов:" + utils.ColorReset)
utils.Code(`- обычный файл (ls показывает -)
d директория (ls показывает d)
l символическая ссылка (ls показывает l)
b блочное устройство (/dev/sda)
c символьное устройство (/dev/tty)
p именованный канал (FIFO)
s сокет`)
// ─── 05. Текстовый интерфейс пользователя ────────────────────
utils.Section("05. Текстовый интерфейс пользователя (CLI)")
utils.Println("Shell (оболочка) — интерпретатор команд между пользователем и ядром.")
fmt.Println()
utils.Println(utils.ColorBold + "Оболочки:" + utils.ColorReset)
utils.Code(`bash Bourne Again Shell, стандарт в большинстве дистро
zsh расширенный bash, Oh My Zsh, популярен у разработчиков
sh POSIX sh (минималистичный, для скриптов)
fish дружелюбный, автодополнение из коробки`)
utils.Println(utils.ColorBold + "Приглашение командной строки (prompt):" + utils.ColorReset)
utils.Code(`user@hostname:~$ обычный пользователь
root@hostname:~# суперпользователь (root)
user имя пользователя
hostname имя машины
~ текущая директория (~ = домашняя)
$ не root; # root`)
utils.Println(utils.ColorBold + "Базовые горячие клавиши:" + utils.ColorReset)
utils.Code(`Tab автодополнение команд и путей
Tab Tab показать все варианты
/ история команд
Ctrl+C прервать текущую команду (SIGINT)
Ctrl+Z приостановить процесс (SIGTSTP)
Ctrl+D закрыть сессию / конец ввода (EOF)
Ctrl+L очистить экран (= clear)
Ctrl+A в начало строки
Ctrl+E в конец строки
Ctrl+R поиск по истории команд
Ctrl+U удалить строку до курсора
Ctrl+W удалить слово влево`)
utils.Println(utils.ColorBold + "Полезные команды общего назначения:" + utils.ColorReset)
utils.Command("man команда", "страница руководства (q — выход, /текст — поиск)")
utils.Command("info команда", "расширенная документация GNU")
utils.Command("команда --help", "краткая справка")
utils.Command("type команда", "что такое команда (alias/builtin/файл)")
utils.Command("which команда", "полный путь к исполняемому файлу")
utils.Command("whereis команда", "бинарник, исходник и man-страница")
utils.Command("history", "история команд")
utils.Command("history 20", "последние 20 команд")
utils.Command("!42", "выполнить команду №42 из истории")
utils.Command("!!", "повторить последнюю команду")
utils.Command("clear", "очистить экран")
utils.Command("exit", "выйти из сессии")
utils.Command("echo $SHELL", "какая оболочка используется")
fmt.Println()
utils.Code(`# Запуск нескольких команд:
cmd1 ; cmd2 выполнить последовательно (всегда)
cmd1 && cmd2 cmd2 только если cmd1 успешна
cmd1 || cmd2 cmd2 только если cmd1 неуспешна
cmd1 | cmd2 передать вывод cmd1 на вход cmd2 (pipe)`)
utils.Note("Виртуальные консоли: Alt+F1..F6 в Linux. В X11 — Ctrl+Alt+F1..F6. Вернуться: Ctrl+Alt+F7.")
utils.Footer()
}

View file

@ -0,0 +1,109 @@
package linuxmodules
import (
"rubric/utils"
)
var KernelModule = Module{
Key: "kernel",
Aliases: []string{"k", "ядро"},
Title: "Ядро Linux",
Description: "Тема 21: ядро, модули, параметры, uname, dmesg",
Run: showKernel,
}
func showKernel() {
utils.Header("Linux — Ядро (Kernel)")
utils.Section("21. Ядро Linux")
utils.Println("Ядро (kernel) — центральная часть ОС. Управляет:")
utils.Println("• процессами и планировщиком CPU")
utils.Println("• памятью (виртуальная память, swap)")
utils.Println("• устройствами (через драйверы)")
utils.Println("• файловыми системами")
utils.Println("• сетью")
utils.Println("• системными вызовами (syscalls)")
utils.Println(utils.ColorBold + "\nИнформация о ядре:" + utils.ColorReset)
utils.Command("uname -r", "версия ядра")
utils.Command("uname -a", "полная информация (ядро, архитектура, дата)")
utils.Command("uname -m", "архитектура (x86_64, aarch64...)")
utils.Command("cat /proc/version", "подробная версия (компилятор, дата)")
utils.Command("cat /proc/sys/kernel/osrelease", "версия через /proc")
utils.Code(`# Пример uname -a:
Linux server01 5.15.0-91-generic #101-Ubuntu SMP Tue Nov 14 13:30:08 UTC 2023
x86_64 x86_64 x86_64 GNU/Linux
платформа
архитектура процессора
имя хоста
имя ядра
# Версия ядра: 5.15.0-91-generic
# 5.15 основная версия
# 0 патч-уровень
# 91 номер пакета дистрибутива`)
utils.Println(utils.ColorBold + "dmesg — буфер сообщений ядра:" + utils.ColorReset)
utils.Command("dmesg", "все сообщения ядра")
utils.Command("dmesg | tail -20", "последние 20 сообщений")
utils.Command("dmesg -T", "с человекочитаемыми временными метками")
utils.Command("dmesg | grep -i error", "только ошибки")
utils.Command("dmesg | grep -i usb", "сообщения о USB-устройствах")
utils.Command("dmesg | grep -i sda", "сообщения о диске sda")
utils.Command("dmesg -w", "следить за новыми сообщениями (как tail -f)")
utils.Command("dmesg -l err,crit", "только критические ошибки")
utils.Println(utils.ColorBold + "\nМодули ядра:" + utils.ColorReset)
utils.Println("Модуль — расширение ядра, загружаемое динамически (драйверы, ФС...).")
utils.Code(`# Управление модулями:
lsmod # список загруженных модулей
lsmod | grep ext4 # есть ли модуль ext4?
modinfo ext4 # информация о модуле
modprobe ext4 # загрузить модуль (с зависимостями)
modprobe -r ext4 # выгрузить модуль
insmod /path/to/mod.ko # загрузить .ko файл напрямую
rmmod ext4 # выгрузить модуль
# Автоматическая загрузка при старте:
# /etc/modules (Debian/Ubuntu)
# /etc/modules-load.d/*.conf
echo "br_netfilter" > /etc/modules-load.d/k8s.conf
# Параметры модулей:
# /etc/modprobe.d/*.conf
echo "options kvm_intel nested=1" > /etc/modprobe.d/kvm.conf`)
utils.Println(utils.ColorBold + "Параметры ядра (sysctl):" + utils.ColorReset)
utils.Code(`# Просмотр параметров:
sysctl -a # все параметры
sysctl net.ipv4.ip_forward # конкретный параметр
cat /proc/sys/net/ipv4/ip_forward # то же через /proc/sys
# Изменить параметр (временно):
sysctl -w net.ipv4.ip_forward=1
# Постоянно в /etc/sysctl.conf или /etc/sysctl.d/:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/99-custom.conf
sysctl -p /etc/sysctl.d/99-custom.conf # применить
# Полезные параметры:
net.ipv4.ip_forward = 1 # маршрутизация (для Docker/Kubernetes)
net.ipv4.tcp_syncookies = 1 # защита от SYN flood
vm.swappiness = 10 # предпочитать RAM над swap
fs.file-max = 2097152 # максимум открытых файлов
kernel.dmesg_restrict = 0 # dmesg без root`)
utils.Println(utils.ColorBold + "Аппаратная информация:" + utils.ColorReset)
utils.Command("lscpu", "информация о процессоре")
utils.Command("lsmem", "информация о памяти")
utils.Command("lspci", "устройства на шине PCI")
utils.Command("lspci -v", "подробно")
utils.Command("lsusb", "USB-устройства")
utils.Command("lsblk", "блочные устройства (диски)")
utils.Command("lshw", "полная информация об оборудовании (нужен root)")
utils.Command("dmidecode", "данные BIOS/UEFI (тип памяти, серийный номер...)")
utils.Command("inxi -Fz", "обзор системы (нужно установить)")
utils.Footer()
}

View file

@ -0,0 +1,175 @@
package linuxmodules
import (
"rubric/utils"
)
var LogsModule = Module{
Key: "logs",
Aliases: []string{"l", "cron", "логи"},
Title: "Логирование и планировщики",
Description: "Темы 3637: rsyslog, journald, cron, at",
Run: showLogs,
}
func showLogs() {
utils.Header("Linux — Логирование и планировщики задач")
// ─── 36. Логирование ──────────────────────────────────────────
utils.Section("36. Логирование")
utils.Println("В современных системах логирование — двухуровневое:")
utils.Println("journald (systemd) + rsyslog/syslog (традиционный)")
utils.Println(utils.ColorBold + "\nОсновные лог-файлы в /var/log/:" + utils.ColorReset)
utils.Code(`/var/log/syslog общий системный лог (Debian/Ubuntu)
/var/log/messages общий системный лог (RHEL/Fedora)
/var/log/auth.log аутентификация, sudo, ssh (Debian)
/var/log/secure аутентификация (RHEL)
/var/log/kern.log сообщения ядра
/var/log/dmesg сообщения при загрузке
/var/log/boot.log процесс загрузки
/var/log/cron задания cron
/var/log/mail.log почтовый сервер
/var/log/nginx/ access.log, error.log
/var/log/apache2/ access.log, error.log
/var/log/mysql/ error.log
/var/log/dpkg.log установка пакетов (Debian)
/var/log/dnf.log установка пакетов (RHEL)
/var/log/wtmp история входов (last для чтения)
/var/log/btmp неудачные попытки входа (lastb)
/var/log/lastlog последний вход каждого пользователя`)
utils.Println(utils.ColorBold + "Работа с логами:" + utils.ColorReset)
utils.Command("tail -f /var/log/syslog", "следить за системным логом")
utils.Command("tail -n 100 /var/log/auth.log", "последние 100 строк лога входов")
utils.Command("grep 'ERROR' /var/log/nginx/error.log", "ошибки nginx")
utils.Command("grep -i 'failed' /var/log/auth.log", "неудачные входы")
utils.Command("zcat /var/log/syslog.1.gz", "читать сжатый архивный лог")
utils.Command("zgrep 'error' /var/log/syslog.*.gz", "поиск в архивных логах")
utils.Command("last", "история входов в систему")
utils.Command("lastb", "неудачные попытки входа (root)")
utils.Command("lastlog", "последний вход каждого пользователя")
utils.Println(utils.ColorBold + "\nrsyslog — конфигурация:" + utils.ColorReset)
utils.Code(`# Конфиг: /etc/rsyslog.conf и /etc/rsyslog.d/*.conf
# Формат правил: facility.priority назначение
# Facility (источник):
auth, authpriv аутентификация
cron планировщик
daemon системные демоны
kern ядро
mail почта
user пользовательские программы
local0..local7 зарезервированы для своего использования
* все
# Priority (уровень, по возрастанию важности):
debug, info, notice, warning, err, crit, alert, emerg
# Примеры правил:
*.info;mail.none;authpriv.none /var/log/messages # всё кроме mail и auth
authpriv.* /var/log/secure # всё от authpriv
mail.* /var/log/maillog # почта
cron.* /var/log/cron # cron
*.emerg :omusrmsg:* # критичное всем пользователям
local1.* /var/log/myapp.log # своё приложение
# Перезапустить rsyslog:
sudo systemctl restart rsyslog`)
utils.Println(utils.ColorBold + "logrotate — ротация логов:" + utils.ColorReset)
utils.Code(`# Конфиг: /etc/logrotate.conf и /etc/logrotate.d/*
# Пример /etc/logrotate.d/nginx:
/var/log/nginx/*.log {
daily # каждый день
missingok # не ошибаться если файл отсутствует
rotate 14 # хранить 14 архивов
compress # сжимать gzip
delaycompress # не сжимать текущий архив
notifempty # не ротировать пустые файлы
create 0640 nginx adm # создать новый файл с правами
sharedscripts
postrotate
nginx -s reopen # сообщить nginx открыть новый файл
endscript
}
# Ручная ротация (тест):
sudo logrotate -d /etc/logrotate.d/nginx # -d = dry run`)
// ─── 37. Планировщики ─────────────────────────────────────────
utils.Section("37. Планировщики задач: cron и at")
utils.Println(utils.ColorBold + "cron — периодические задачи:" + utils.ColorReset)
utils.Code(`# Редактировать crontab текущего пользователя:
crontab -e
# Посмотреть:
crontab -l
# Удалить все задачи:
crontab -r
# Для root:
sudo crontab -e
# Формат строки crontab:
# мин час день_месяца месяц день_недели команда
# 0-59 0-23 1-31 1-12 0-7(0,7=воскресенье)
# Примеры:
* * * * * /script.sh # каждую минуту
0 * * * * /script.sh # каждый час в 0 минут
0 2 * * * /backup.sh # каждый день в 02:00
0 2 * * 0 /weekly.sh # каждое воскресенье в 02:00
0 2 1 * * /monthly.sh # 1-го числа каждого месяца
*/5 * * * * /check.sh # каждые 5 минут
0 9-17 * * 1-5 /work.sh # по будням с 9 до 17
0 2 * * * root /root/backup.sh # в /etc/crontab с указанием пользователя
# Специальные строки:
@reboot /script.sh # при каждой загрузке
@daily /script.sh # раз в день (= 0 0 * * *)
@weekly /script.sh # раз в неделю
@monthly /script.sh # раз в месяц
@yearly /script.sh # раз в год`)
utils.Println(utils.ColorBold + "Системные cron-директории:" + utils.ColorReset)
utils.Code(`/etc/crontab системный crontab (с полем user)
/etc/cron.d/ отдельные файлы crontab
/etc/cron.hourly/ скрипты, запускаемые каждый час
/etc/cron.daily/ каждый день
/etc/cron.weekly/ каждую неделю
/etc/cron.monthly/ каждый месяц
# Поместить скрипт в /etc/cron.daily/:
sudo cp backup.sh /etc/cron.daily/
sudo chmod +x /etc/cron.daily/backup.sh`)
utils.Println(utils.ColorBold + "at — однократные задачи:" + utils.ColorReset)
utils.Code(`# Выполнить команду однократно в указанное время:
at 14:30 # в 14:30 сегодня
at 14:30 tomorrow # завтра в 14:30
at 14:30 July 15 # 15 июля
at now + 1 hour # через час
at now + 30 minutes # через 30 минут
# Ввод команд (Ctrl+D для завершения):
at 02:00
> /usr/local/bin/backup.sh
> Ctrl+D
# Список задач:
atq
at -l
# Удалить задачу:
atrm 5 # удалить задачу 5
# Посмотреть содержимое задачи:
at -c 5`)
utils.Footer()
}

View file

@ -0,0 +1,346 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var NetfsModule = Module{
Key: "netfs",
Aliases: []string{"nfs", "smb", "samba", "autofs", "сетевые-фс"},
Title: "Сетевые файловые системы",
Description: "Темы 5559: IPv6, передача файлов, NFS, SMB/Samba, autofs",
Run: showNetfs,
}
func showNetfs() {
utils.Header("Linux — Сетевые файловые системы")
// ─── 55. IPv6 ─────────────────────────────────────────────────
utils.Section("55. Работа с IPv6")
utils.Println("IPv6 — протокол интернета следующего поколения (128-битные адреса).")
fmt.Println()
utils.Println(utils.ColorBold + "Формат IPv6 адресов:" + utils.ColorReset)
utils.Code(`Формат: 8 групп по 4 hex-цифры, разделённых :
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Сокращения:
- Ведущие нули в группе можно опустить: 0db8 db8
- Одну последовательность групп из нулей ::
2001:db8::1 (полный: 2001:0db8:0000:0000:0000:0000:0000:0001)
::1 loopback (аналог 127.0.0.1)
fe80::/10 link-local (автоконфигурация в подсети)
fd00::/8 уникальные локальные (аналог 192.168.x.x)
2000::/3 глобальные unicast (публичные)
Длина префикса: 2001:db8::/32 (аналог маски подсети)`)
utils.Println(utils.ColorBold + "Настройка IPv6 через nmcli:" + utils.ColorReset)
utils.Code(`# Статический IPv6:
nmcli con mod eth0 ipv6.addresses "2001:db8::10/64"
nmcli con mod eth0 ipv6.gateway "2001:db8::1"
nmcli con mod eth0 ipv6.method manual
nmcli con up eth0
# SLAAC (автоконфигурация):
nmcli con mod eth0 ipv6.method auto
# DHCPv6:
nmcli con mod eth0 ipv6.method dhcp
# Отключить IPv6 для интерфейса:
nmcli con mod eth0 ipv6.method disabled`)
utils.Println(utils.ColorBold + "IPv6 команды:" + utils.ColorReset)
utils.Command("ip -6 addr", "IPv6 адреса интерфейсов")
utils.Command("ip -6 route", "IPv6 таблица маршрутов")
utils.Command("ping6 ::1", "ping loopback IPv6")
utils.Command("ping6 fe80::1%eth0", "ping link-local с указанием интерфейса")
utils.Command("traceroute6 2001:4860:4860::8888", "traceroute IPv6")
utils.Command("ss -6 -tuln", "IPv6 порты")
utils.Command("dig AAAA google.com", "DNS AAAA запись (IPv6)")
// ─── 56. Передача файлов по сети ─────────────────────────────
utils.Section("56. Передача файлов по сети")
utils.Println(utils.ColorBold + "SCP — копирование через SSH:" + utils.ColorReset)
utils.Code(`# Скопировать локальный файл на сервер:
scp file.txt user@server:/path/to/dest/
# Скопировать с сервера на локальную машину:
scp user@server:/path/file.txt /local/path/
# Директорию рекурсивно:
scp -r mydir/ user@server:/tmp/
# Нестандартный порт:
scp -P 2222 file.txt user@server:/tmp/
# С указанием ключа:
scp -i ~/.ssh/mykey file.txt user@server:/tmp/
# Между двумя серверами:
scp user1@server1:/path/file.txt user2@server2:/path/`)
utils.Println(utils.ColorBold + "SFTP — интерактивная передача файлов:" + utils.ColorReset)
utils.Code(`# Подключиться:
sftp user@server
sftp -P 2222 user@server
# Команды в интерактивном режиме:
ls список файлов на сервере
lls список файлов локально
pwd директория на сервере
lpwd локальная директория
cd /remote/path перейти на сервере
lcd /local/path перейти локально
get file.txt скачать файл
get -r dir/ скачать директорию
put file.txt загрузить файл
put -r dir/ загрузить директорию
rm file.txt удалить на сервере
mkdir newdir создать директорию на сервере
exit / quit выйти`)
utils.Println(utils.ColorBold + "rsync — эффективная синхронизация:" + utils.ColorReset)
utils.Code(`# rsync передаёт только изменения быстрее scp для больших объёмов.
# Синхронизировать локально:
rsync -av /source/ /dest/
# Синхронизировать на удалённый сервер:
rsync -avz /local/data/ user@server:/remote/data/
# С сервера локально:
rsync -avz user@server:/remote/data/ /local/data/
# Ключи:
# -a архивный режим (сохраняет права, время, симлинки)
# -v verbose
# -z сжатие при передаче
# -P прогресс + продолжение прерванной передачи
# --delete удалять файлы которых нет в источнике
# --exclude='*.log' исключить паттерн
# -n / --dry-run симуляция (что будет скопировано)
# -e "ssh -p 2222" нестандартный порт SSH
# Зеркалирование с исключениями:
rsync -avz --delete \
--exclude='.git/' \
--exclude='node_modules/' \
/project/ user@server:/var/www/project/`)
// ─── 57. NFS ──────────────────────────────────────────────────
utils.Section("57. Сетевые файловые системы — NFS")
utils.Println("NFS (Network File System) — монтирование директорий с удалённых серверов.")
utils.Println("Прозрачно для приложений: работает как обычная локальная ФС.")
fmt.Println()
utils.Println(utils.ColorBold + "Сервер NFS — настройка экспорта:" + utils.ColorReset)
utils.Code(`# Установка:
dnf install nfs-utils # RHEL/Fedora
apt install nfs-kernel-server # Debian/Ubuntu
# Включить и запустить:
systemctl enable --now nfs-server # RHEL
systemctl enable --now nfs-kernel-server # Ubuntu
# Настройка экспортов /etc/exports:
# директория клиент(опции)
/shared 192.168.1.0/24(rw,sync,no_root_squash)
/data *(ro,sync) # всем только чтение
/home/alice server2(rw,sync,no_subtree_check)
# Опции:
# rw чтение и запись
# ro только чтение
# sync синхронная запись (безопасно)
# async асинхронная (быстрее, риск потери)
# no_root_squash root клиента = root сервера
# root_squash root клиента nobody (безопаснее, по умолчанию)
# no_subtree_check не проверять поддерево (производительность)
# Применить изменения:
exportfs -r # перечитать /etc/exports
exportfs -v # показать активные экспорты
exportfs -a # экспортировать всё из /etc/exports`)
utils.Println(utils.ColorBold + "Firewall для NFS:" + utils.ColorReset)
utils.Code(`firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-service=rpc-bind
firewall-cmd --permanent --add-service=mountd
firewall-cmd --reload`)
utils.Println(utils.ColorBold + "Клиент NFS — монтирование:" + utils.ColorReset)
utils.Code(`# Установка клиента:
dnf install nfs-utils
apt install nfs-common
# Посмотреть экспорты сервера:
showmount -e 192.168.1.10
# Смонтировать:
mount -t nfs 192.168.1.10:/shared /mnt/shared
mount -t nfs4 192.168.1.10:/data /mnt/data # NFSv4
# Параметры монтирования:
mount -t nfs -o rw,sync,hard,intr 192.168.1.10:/shared /mnt
# В /etc/fstab (постоянно):
192.168.1.10:/shared /mnt/shared nfs defaults,_netdev 0 0
# _netdev монтировать только после настройки сети
# Размонтировать:
umount /mnt/shared`)
// ─── 58. SMB/Samba ────────────────────────────────────────────
utils.Section("58. Сетевые файловые системы — SMB/Samba")
utils.Println("SMB (Server Message Block) / CIFS — протокол файлового обмена Windows.")
utils.Println("Samba — реализация SMB на Linux. Позволяет обмениваться файлами с Windows.")
fmt.Println()
utils.Println(utils.ColorBold + "Сервер Samba — установка и настройка:" + utils.ColorReset)
utils.Code(`# Установка:
dnf install samba samba-client # RHEL
apt install samba # Ubuntu
# Включить и запустить:
systemctl enable --now smb nmb # RHEL
systemctl enable --now smbd nmbd # Ubuntu`)
utils.Println(utils.ColorBold + "Конфигурация /etc/samba/smb.conf:" + utils.ColorReset)
utils.Code(`[global]
workgroup = WORKGROUP # рабочая группа Windows
server string = Samba Server
security = user # аутентификация по пользователю
passdb backend = tdbsam # база паролей
# Публичная шара (без пароля):
[public]
path = /srv/samba/public
browseable = yes
writable = yes
guest ok = yes
create mask = 0664
directory mask = 0775
# Приватная шара (с паролем):
[private]
path = /srv/samba/private
valid users = alice bob
writable = yes
browseable = no
create mask = 0660`)
utils.Println(utils.ColorBold + "Управление пользователями Samba:" + utils.ColorReset)
utils.Code(`# Пользователь Samba должен существовать в Linux:
useradd -s /sbin/nologin alice
# Добавить пользователя в Samba (отдельный пароль!):
smbpasswd -a alice
smbpasswd -e alice # включить
smbpasswd -d alice # отключить
smbpasswd -x alice # удалить
# Список пользователей Samba:
pdbedit -L`)
utils.Println(utils.ColorBold + "SELinux + Samba:" + utils.ColorReset)
utils.Code(`# Разрешить Samba доступ к домашним директориям:
setsebool -P samba_enable_home_dirs on
# Разрешить Samba читать/писать общие директории:
chcon -t samba_share_t /srv/samba/public
semanage fcontext -a -t samba_share_t '/srv/samba(/.*)?'
restorecon -Rv /srv/samba/`)
utils.Println(utils.ColorBold + "Firewall для Samba:" + utils.ColorReset)
utils.Code(`firewall-cmd --permanent --add-service=samba
firewall-cmd --reload`)
utils.Println(utils.ColorBold + "Клиент SMB — монтирование Windows-шары:" + utils.ColorReset)
utils.Code(`# Установка:
dnf install cifs-utils samba-client
apt install cifs-utils smbclient
# Просмотр шар на сервере:
smbclient -L //192.168.1.20 -U alice
# Интерактивный клиент:
smbclient //192.168.1.20/shared -U alice
# Монтирование:
mount -t cifs //192.168.1.20/shared /mnt/windows \
-o username=alice,password=secret
# С файлом учётных данных (безопаснее):
cat > /etc/samba/creds << 'EOF'
username=alice
password=secret
domain=WORKGROUP
EOF
chmod 600 /etc/samba/creds
mount -t cifs //192.168.1.20/shared /mnt/windows \
-o credentials=/etc/samba/creds
# В /etc/fstab:
//server/shared /mnt/windows cifs credentials=/etc/samba/creds,_netdev 0 0`)
// ─── 59. Autofs ───────────────────────────────────────────────
utils.Section("59. Автоматическое монтирование — Autofs")
utils.Println("Autofs — демон автоматического монтирования сетевых ФС по запросу.")
utils.Println("Монтирует при обращении к директории, размонтирует при простое.")
fmt.Println()
utils.Println(utils.ColorBold + "Установка и запуск:" + utils.ColorReset)
utils.Code(`dnf install autofs # RHEL
apt install autofs # Ubuntu
systemctl enable --now autofs`)
utils.Println(utils.ColorBold + "Конфигурация autofs:" + utils.ColorReset)
utils.Code(`# Главный файл /etc/auto.master:
# точкаонтирования файл_карты [опции]
/mnt/nfs /etc/auto.nfs --timeout=60
/home /etc/auto.home --timeout=300
/- /etc/auto.direct
# /etc/auto.nfs монтирование NFS:
# ключ опции сервер:путь
shared -rw,sync 192.168.1.10:/shared
data -ro 192.168.1.10:/data
# Обращение: ls /mnt/nfs/shared автоматически монтируется
# /etc/auto.home домашние директории через NFS:
* -rw,sync 192.168.1.10:/home/&
# & подставляется ключ (* = любой пользователь)
# /home/alice монтируется 192.168.1.10:/home/alice
# /etc/auto.direct прямые точки монтирования:
/srv/data -rw,sync 192.168.1.10:/data
# Применить изменения:
systemctl reload autofs
# или:
automount -v`)
utils.Println(utils.ColorBold + "Использование с FreeIPA/LDAP:" + utils.ColorReset)
utils.Code(`# FreeIPA хранит карты autofs в LDAP.
# После настройки sssd + ipa-client autofs
# получает карты автоматически.
# Подключить autofs к SSSD:
# В /etc/sssd/sssd.conf:
[domain/ipa.example.com]
autofs_provider = ipa
# Перезапустить:
systemctl restart sssd autofs`)
utils.Note("Autofs удобен для сотен пользователей: их домашние директории монтируются автоматически при входе.")
utils.Note("--timeout=60 означает размонтировать после 60 секунд бездействия.")
utils.Footer()
}

View file

@ -0,0 +1,238 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var NetworkModule = Module{
Key: "network",
Aliases: []string{"net", "ssh", "сеть"},
Title: "Сети и SSH",
Description: "Темы 4244: основы сетей, настройка, SSH",
Run: showNetwork,
}
func showNetwork() {
utils.Header("Linux — Сети и SSH")
// ─── 42. Основы сетей ─────────────────────────────────────────
utils.Section("42. Основы сетей")
utils.Println(utils.ColorBold + "Ключевые понятия:" + utils.ColorReset)
utils.Code(`IP-адрес уникальный адрес устройства в сети
IPv4: 192.168.1.10 (4 байта, 0-255)
IPv6: 2001:db8::1 (16 байт, hex)
Маска сети определяет границу сети и хостов
/24 = 255.255.255.0 (256 адресов, 254 хоста)
/16 = 255.255.0.0 (65536 адресов)
Шлюз маршрутизатор для выхода за пределы сети
DNS перевод имён в IP (8.8.8.8 = Google DNS)
MAC-адрес физический адрес сетевого интерфейса
DHCP автоматическое получение IP от сервера
Приватные сети (RFC 1918):
10.0.0.0/8 (10.x.x.x)
172.16.0.0/12 (172.16-31.x.x)
192.168.0.0/16 (192.168.x.x)
Localhost:
127.0.0.1 loopback IPv4 (lo)
::1 loopback IPv6`)
utils.Println(utils.ColorBold + "Информация о сетевых интерфейсах:" + utils.ColorReset)
utils.Command("ip addr", "IP-адреса всех интерфейсов")
utils.Command("ip addr show eth0", "конкретный интерфейс")
utils.Command("ip link", "состояние интерфейсов (UP/DOWN)")
utils.Command("ip route", "таблица маршрутизации")
utils.Command("ip route show default", "шлюз по умолчанию")
utils.Command("ip neigh", "ARP-таблица (MAC → IP)")
fmt.Println()
utils.Code(`# Старые команды (net-tools, устаревшие):
ifconfig # ip addr
route -n # ip route
netstat -rn # ip route
arp -n # ip neigh`)
utils.Println(utils.ColorBold + "Диагностика сети:" + utils.ColorReset)
utils.Command("ping 8.8.8.8", "проверить доступность хоста")
utils.Command("ping -c 4 google.com", "4 пакета")
utils.Command("ping6 ::1", "ping для IPv6")
utils.Command("traceroute google.com", "маршрут до хоста")
utils.Command("tracepath google.com", "маршрут (без root)")
utils.Command("mtr google.com", "ping + traceroute в реальном времени")
utils.Command("nslookup google.com", "DNS-запрос")
utils.Command("dig google.com", "подробный DNS-запрос")
utils.Command("dig @8.8.8.8 google.com", "DNS через конкретный сервер")
utils.Command("host google.com", "быстрый DNS-запрос")
utils.Command("whois 192.168.1.1", "информация об IP/домене")
fmt.Println()
utils.Println(utils.ColorBold + "Сетевые соединения и порты:" + utils.ColorReset)
utils.Command("ss -tuln", "прослушиваемые порты (t=tcp u=udp l=listen n=numeric)")
utils.Command("ss -tulnp", "с именами процессов (root)")
utils.Command("ss -s", "статистика соединений")
utils.Command("ss -tn state established", "активные TCP-соединения")
utils.Command("netstat -tuln", "аналог ss (устаревший)")
utils.Command("lsof -i :80", "что слушает порт 80")
utils.Command("lsof -i :22", "что слушает порт 22")
utils.Command("nmap -sS 192.168.1.0/24", "сканирование сети (нужно установить)")
utils.Command("nmap -p 22,80,443 server", "проверить конкретные порты")
// ─── 43. Работа с сетью ───────────────────────────────────────
utils.Section("43. Настройка сети")
utils.Println(utils.ColorBold + "Временная настройка (без сохранения):" + utils.ColorReset)
utils.Code(`# Добавить IP:
ip addr add 192.168.1.10/24 dev eth0
# Удалить IP:
ip addr del 192.168.1.10/24 dev eth0
# Включить/выключить интерфейс:
ip link set eth0 up
ip link set eth0 down
# Добавить маршрут:
ip route add 10.0.0.0/8 via 192.168.1.1
ip route add default via 192.168.1.1
# Удалить маршрут:
ip route del default`)
utils.Println(utils.ColorBold + "NetworkManager — постоянная настройка:" + utils.ColorReset)
utils.Code(`# nmcli командная строка NetworkManager
nmcli device status # список устройств
nmcli connection show # все соединения
nmcli connection show eth0 # параметры соединения
# Статический IP:
nmcli con mod eth0 ipv4.addresses 192.168.1.10/24
nmcli con mod eth0 ipv4.gateway 192.168.1.1
nmcli con mod eth0 ipv4.dns "8.8.8.8 8.8.4.4"
nmcli con mod eth0 ipv4.method manual # static (не DHCP)
nmcli con up eth0 # применить
# DHCP:
nmcli con mod eth0 ipv4.method auto
nmcli con up eth0
# Создать соединение:
nmcli con add type ethernet con-name myconn ifname eth1 \
ipv4.addresses 10.0.0.5/24 ipv4.gateway 10.0.0.1 \
ipv4.method manual
# nmtui псевдографический интерфейс:
nmtui`)
utils.Println(utils.ColorBold + "DNS-настройка:" + utils.ColorReset)
utils.Code(`# /etc/resolv.conf DNS-серверы:
nameserver 8.8.8.8
nameserver 8.8.4.4
search mydomain.local # домен для коротких имён
# /etc/hosts локальное разрешение имён:
127.0.0.1 localhost
192.168.1.10 server01.local server01
# Порядок разрешения (/etc/nsswitch.conf):
hosts: files dns myhostname # сначала /etc/hosts, потом DNS`)
utils.Println(utils.ColorBold + "curl и wget — HTTP-запросы:" + utils.ColorReset)
utils.Command("curl https://example.com", "GET запрос")
utils.Command("curl -I https://example.com", "только заголовки")
utils.Command("curl -o file.txt https://example.com/file", "сохранить в файл")
utils.Command("curl -L https://example.com", "следовать перенаправлениям")
utils.Command("curl -X POST -d 'data' https://api.example.com", "POST запрос")
utils.Command("curl -H 'Authorization: Bearer token' https://api.example.com", "с заголовком")
utils.Command("wget https://example.com/file.tar.gz", "скачать файл")
utils.Command("wget -r -np https://example.com/docs/", "рекурсивно скачать")
// ─── 44. SSH ──────────────────────────────────────────────────
utils.Section("44. Удалённый доступ — SSH")
utils.Println("SSH (Secure Shell) — зашифрованный протокол удалённого доступа.")
fmt.Println()
utils.Println(utils.ColorBold + "Подключение:" + utils.ColorReset)
utils.Command("ssh user@server", "подключиться к серверу")
utils.Command("ssh user@192.168.1.10", "по IP")
utils.Command("ssh -p 2222 user@server", "нестандартный порт")
utils.Command("ssh -i ~/.ssh/mykey user@server", "с конкретным ключом")
utils.Command("ssh -v user@server", "подробный вывод (отладка)")
utils.Command("ssh -A user@server", "пробросить SSH-агент")
fmt.Println()
utils.Println(utils.ColorBold + "SSH-ключи — аутентификация без пароля:" + utils.ColorReset)
utils.Code(`# Генерация пары ключей:
ssh-keygen -t ed25519 -C "alice@example.com" # (рекомендуется)
ssh-keygen -t rsa -b 4096 -C "alice@example.com" # RSA 4096
# Файлы:
~/.ssh/id_ed25519 приватный ключ (НИКОМУ не передавать!)
~/.ssh/id_ed25519.pub публичный ключ
# Скопировать публичный ключ на сервер:
ssh-copy-id user@server # автоматически
ssh-copy-id -i ~/.ssh/mykey.pub user@server
# Вручную (добавить в ~/.ssh/authorized_keys на сервере):
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh/`)
utils.Println(utils.ColorBold + "~/.ssh/config — настройка подключений:" + utils.ColorReset)
utils.Code(`# ~/.ssh/config
Host myserver
HostName 192.168.1.10
User alice
Port 22
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
Host bastion
HostName bastion.example.com
User admin
ForwardAgent yes
Host internal
HostName 10.0.0.5
User root
ProxyJump bastion # подключиться через bastion
# Использование:
ssh myserver # вместо ssh alice@192.168.1.10 -i ~/.ssh/id_ed25519`)
utils.Println(utils.ColorBold + "Передача файлов:" + utils.ColorReset)
utils.Command("scp file.txt user@server:/path/", "скопировать на сервер")
utils.Command("scp user@server:/path/file.txt .", "скопировать с сервера")
utils.Command("scp -r dir/ user@server:/path/", "директорию рекурсивно")
utils.Command("rsync -avzP dir/ user@server:/path/", "синхронизация (лучше scp)")
fmt.Println()
utils.Println(utils.ColorBold + "Конфигурация сервера (/etc/ssh/sshd_config):" + utils.ColorReset)
utils.Code(`Port 22 # порт (лучше изменить)
PermitRootLogin no # запретить вход root (рекомендуется)
PasswordAuthentication no # только ключи
PubkeyAuthentication yes # ключи разрешены
AuthorizedKeysFile .ssh/authorized_keys
AllowUsers alice bob # только эти пользователи
MaxAuthTries 3 # попытки аутентификации
# Применить изменения:
sudo systemctl reload sshd
# Проверить конфигурацию:
sudo sshd -t`)
utils.Println(utils.ColorBold + "Туннели SSH (Port Forwarding):" + utils.ColorReset)
utils.Code(`# Локальный туннель (доступ к удалённому сервису через localhost):
ssh -L 8080:localhost:80 user@server
# Теперь http://localhost:8080 = http://server:80
# Удалённый туннель (открыть порт на удалённом сервере):
ssh -R 9090:localhost:3000 user@server
# Теперь server:9090 localhost:3000
# SOCKS-прокси (динамический туннель):
ssh -D 1080 user@server
# Настроить браузер на SOCKS5 proxy localhost:1080`)
utils.Footer()
}

View file

@ -0,0 +1,191 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var PackagesModule = Module{
Key: "packages",
Aliases: []string{"pkg", "dnf", "apt", "пакеты"},
Title: "Пакетный менеджер",
Description: "Тема 47: dnf (RHEL/Fedora) и apt (Debian/Ubuntu)",
Run: showPackages,
}
func showPackages() {
utils.Header("Linux — Пакетный менеджер")
utils.Section("47. Пакетные менеджеры: dnf и apt")
utils.Println("Пакетный менеджер — инструмент установки, обновления и удаления ПО.")
utils.Println("Решает зависимости автоматически, загружает из репозиториев.")
fmt.Println()
utils.Println(utils.ColorBold + "Семейства дистрибутивов и их менеджеры:" + utils.ColorReset)
utils.Code(`RHEL / CentOS / Fedora / Rocky / AlmaLinux:
dnf (современный) / yum (устаревший)
Формат пакетов: .rpm
Репозитории: /etc/yum.repos.d/*.repo
Debian / Ubuntu / Linux Mint:
apt (фронтенд) / dpkg (низкий уровень)
Формат пакетов: .deb
Репозитории: /etc/apt/sources.list, /etc/apt/sources.list.d/
Arch Linux:
pacman
Alpine Linux:
apk`)
// ─── dnf ──────────────────────────────────────────────────────
utils.Section("dnf — RHEL / Fedora / CentOS")
utils.Println(utils.ColorBold + "Основные операции:" + utils.ColorReset)
utils.Command("dnf search nginx", "поиск пакета")
utils.Command("dnf info nginx", "информация о пакете")
utils.Command("dnf install nginx", "установить")
utils.Command("dnf install nginx -y", "без подтверждения")
utils.Command("dnf remove nginx", "удалить")
utils.Command("dnf update", "обновить все пакеты")
utils.Command("dnf update nginx", "обновить конкретный")
utils.Command("dnf upgrade --refresh", "обновить с принудительным обновлением метаданных")
utils.Command("dnf check-update", "показать доступные обновления")
fmt.Println()
utils.Println(utils.ColorBold + "Запросы и история:" + utils.ColorReset)
utils.Command("dnf list installed", "установленные пакеты")
utils.Command("dnf list available", "доступные пакеты")
utils.Command("dnf list | grep nginx", "найти в списке")
utils.Command("dnf provides /usr/bin/python3", "какой пакет предоставляет файл")
utils.Command("dnf provides '*/Makefile'", "поиск по glob")
utils.Command("rpm -ql nginx", "файлы установленного пакета")
utils.Command("rpm -qf /etc/nginx/nginx.conf", "какому пакету принадлежит файл")
utils.Command("rpm -qi nginx", "информация об установленном пакете")
utils.Command("dnf history", "история операций")
utils.Command("dnf history undo 5", "отменить операцию №5")
fmt.Println()
utils.Println(utils.ColorBold + "Группы пакетов:" + utils.ColorReset)
utils.Command("dnf group list", "список групп")
utils.Command("dnf group info 'Development Tools'", "информация о группе")
utils.Command("dnf group install 'Development Tools'", "установить группу")
utils.Command("dnf group remove 'Development Tools'", "удалить группу")
fmt.Println()
utils.Println(utils.ColorBold + "Репозитории:" + utils.ColorReset)
utils.Code(`# Список репозиториев:
dnf repolist
dnf repolist all # включая отключённые
# Включить/выключить репозиторий:
dnf config-manager --enable epel
dnf config-manager --disable crb
# Добавить репозиторий:
dnf install epel-release # EPEL (Extra Packages for Enterprise Linux)
dnf config-manager --add-repo https://rpm.example.com/example.repo
# Установить из конкретного репозитория:
dnf install nginx --repo=epel
# Файл репозитория (/etc/yum.repos.d/myrepo.repo):
[myrepo]
name=My Repository
baseurl=https://repo.example.com/rhel/$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.example.com/RPM-GPG-KEY-myrepo`)
utils.Println(utils.ColorBold + "Кэш и модули:" + utils.ColorReset)
utils.Command("dnf clean all", "очистить кэш")
utils.Command("dnf makecache", "обновить кэш метаданных")
utils.Command("dnf autoremove", "удалить ненужные зависимости")
utils.Command("dnf module list", "список модулей (AppStream)")
utils.Command("dnf module install nodejs:18", "установить модуль nodejs версии 18")
utils.Command("dnf module enable postgresql:15", "включить модуль")
// ─── apt ──────────────────────────────────────────────────────
utils.Section("apt — Debian / Ubuntu")
utils.Println(utils.ColorBold + "Основные операции:" + utils.ColorReset)
utils.Command("apt search nginx", "поиск пакета")
utils.Command("apt show nginx", "информация о пакете")
utils.Command("apt install nginx", "установить")
utils.Command("apt install nginx -y", "без подтверждения")
utils.Command("apt remove nginx", "удалить (конфиги остаются)")
utils.Command("apt purge nginx", "удалить с конфигами")
utils.Command("apt update", "обновить индекс репозиториев (метаданные)")
utils.Command("apt upgrade", "обновить установленные пакеты")
utils.Command("apt full-upgrade", "обновить, может удалять и устанавливать новые")
utils.Command("apt dist-upgrade", "аналог full-upgrade")
utils.Command("apt autoremove", "удалить ненужные зависимости")
utils.Command("apt clean", "очистить кэш скачанных пакетов")
utils.Command("apt autoclean", "очистить устаревший кэш")
fmt.Println()
utils.Println(utils.ColorBold + "Запросы:" + utils.ColorReset)
utils.Command("apt list --installed", "установленные пакеты")
utils.Command("apt list --upgradable", "пакеты с доступными обновлениями")
utils.Command("dpkg -l nginx", "статус установленного пакета")
utils.Command("dpkg -L nginx", "файлы установленного пакета")
utils.Command("dpkg -S /etc/nginx/nginx.conf", "какому пакету принадлежит файл")
utils.Command("dpkg -s nginx", "информация об установленном пакете")
fmt.Println()
utils.Println(utils.ColorBold + "Репозитории (Debian/Ubuntu):" + utils.ColorReset)
utils.Code(`# Конфиг: /etc/apt/sources.list
# Ubuntu 22.04:
deb http://ru.archive.ubuntu.com/ubuntu jammy main restricted
deb http://ru.archive.ubuntu.com/ubuntu jammy-updates main restricted
deb http://security.ubuntu.com/ubuntu jammy-security main restricted
# Добавить PPA (Ubuntu):
add-apt-repository ppa:ondrej/php
apt update
apt install php8.3
# Добавить сторонний репозиторий (пример nginx):
# 1. Импортировать GPG-ключ:
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
-o /etc/apt/keyrings/nginx.gpg
# 2. Добавить репозиторий:
echo "deb [signed-by=/etc/apt/keyrings/nginx.gpg] \
http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
> /etc/apt/sources.list.d/nginx.list
# 3. Обновить и установить:
apt update && apt install nginx
# Файл в /etc/apt/sources.list.d/: формат .list или .sources (deb822)`)
utils.Println(utils.ColorBold + "Низкоуровневые операции (dpkg):" + utils.ColorReset)
utils.Code(`# Установить .deb файл:
dpkg -i package.deb
apt install -f # исправить зависимости после dpkg
# Удалить:
dpkg -r package # без конфигов
dpkg -P package # с конфигами (purge)
# Reconfigure (перенастроить):
dpkg-reconfigure tzdata
dpkg-reconfigure locales`)
utils.Println(utils.ColorBold + "Общие инструменты управления ПО:" + utils.ColorReset)
utils.Code(`# Snap (Ubuntu, кросс-дистрибутивный):
snap install code --classic
snap list
snap remove code
snap refresh
# Flatpak (кросс-дистрибутивный):
flatpak install flathub org.gimp.GIMP
flatpak run org.gimp.GIMP
flatpak list
# pip (Python):
pip install requests
pip install -r requirements.txt
pip list
# npm (Node.js):
npm install -g pm2
npm list -g`)
utils.Footer()
}

View file

@ -0,0 +1,264 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var PerformanceModule = Module{
Key: "performance",
Aliases: []string{"perf", "swap", "tuned", "производительность"},
Title: "Производительность системы",
Description: "Темы 4952: виртуальная память, планировщик CPU, tuned, Stratis",
Run: showPerformance,
}
func showPerformance() {
utils.Header("Linux — Производительность системы")
// ─── 49. Виртуальная память, swap ────────────────────────────
utils.Section("49. Виртуальная память и swap")
utils.Println("Виртуальная память — механизм ядра, позволяющий процессам иметь")
utils.Println("больше памяти, чем физически установлено, за счёт использования диска.")
fmt.Println()
utils.Println(utils.ColorBold + "Swap — раздел/файл подкачки:" + utils.ColorReset)
utils.Code(`Когда физической RAM не хватает, ядро перемещает
редко используемые страницы памяти на swap.
Это медленнее RAM в сотни раз, но лучше OOM-killer.
Типы swap:
- раздел swap (swap partition) отдельный раздел диска
- файл swap (swapfile) обычный файл на любой ФС`)
utils.Println(utils.ColorBold + "Просмотр swap:" + utils.ColorReset)
utils.Command("free -h", "RAM и swap (human-readable)")
utils.Command("swapon --show", "активные swap-устройства")
utils.Command("cat /proc/swaps", "то же через /proc")
utils.Command("vmstat -s", "статистика памяти и swap")
fmt.Println()
utils.Println(utils.ColorBold + "Создание swapfile:" + utils.ColorReset)
utils.Code(`# 1. Создать файл нужного размера:
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 # 2 ГБ
# или быстрее:
sudo fallocate -l 2G /swapfile
# 2. Установить права (только root):
sudo chmod 600 /swapfile
# 3. Форматировать как swap:
sudo mkswap /swapfile
# 4. Активировать:
sudo swapon /swapfile
# 5. Добавить в /etc/fstab для автоматической активации:
echo '/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab`)
utils.Println(utils.ColorBold + "Управление swap:" + utils.ColorReset)
utils.Command("swapon /dev/sdb2", "активировать swap-раздел")
utils.Command("swapoff /swapfile", "деактивировать")
utils.Command("swapoff -a", "деактивировать все swap")
utils.Command("swapon -a", "активировать все из /etc/fstab")
fmt.Println()
utils.Println(utils.ColorBold + "vm.swappiness — настройка агрессивности swap:" + utils.ColorReset)
utils.Code(`# swappiness: 0100
# 0 использовать swap только при нехватке RAM
# 60 по умолчанию
# 100 активно перемещать страницы в swap
# Посмотреть:
cat /proc/sys/vm/swappiness
sysctl vm.swappiness
# Изменить временно:
sudo sysctl -w vm.swappiness=10
# Постоянно в /etc/sysctl.d/99-swap.conf:
vm.swappiness = 10
vm.vfs_cache_pressure = 50 # агрессивность освобождения кэша inode`)
utils.Println(utils.ColorBold + "OOM-killer (Out Of Memory):" + utils.ColorReset)
utils.Code(`Когда память (RAM + swap) исчерпана, ядро убивает процессы.
# Посмотреть OOM-события в логах:
dmesg | grep -i "oom\|killed process"
journalctl -k | grep -i oom
# oom_score чем выше, тем вероятнее убийство:
cat /proc/PID/oom_score
# Защитить процесс от OOM (от -17 до 15):
echo -1000 > /proc/PID/oom_score_adj # максимальная защита
# или через systemd в юните:
OOMScoreAdjust=-1000`)
// ─── 50. Планировщик процессов ───────────────────────────────
utils.Section("50. Планировщик процессов")
utils.Println("Планировщик CPU распределяет процессорное время между процессами.")
fmt.Println()
utils.Println(utils.ColorBold + "Политики планирования:" + utils.ColorReset)
utils.Code(`SCHED_OTHER обычные процессы (CFS Completely Fair Scheduler)
SCHED_FIFO реального времени, без вытеснения
SCHED_RR реального времени, с квантованием
SCHED_BATCH фоновые задачи (CPU-bound)
SCHED_IDLE минимальный приоритет (ниже nice 19)
SCHED_DEADLINE задачи с дедлайном`)
utils.Println(utils.ColorBold + "nice и renice — управление приоритетом:" + utils.ColorReset)
utils.Code(`# Nice: -20 (высший приоритет) 19 (низший)
# По умолчанию: 0
# Только root может установить отрицательные значения
# Запустить с пониженным приоритетом:
nice -n 15 make -j8 # фоновая сборка
# Запустить с повышенным (root):
sudo nice -n -10 realtime_app
# Изменить приоритет запущенного процесса:
renice -n 5 -p 1234 # по PID
renice -n 10 -u alice # всем процессам пользователя
sudo renice -n -5 -p 1234 # повысить (нужен root)`)
utils.Println(utils.ColorBold + "chrt — управление политикой планирования:" + utils.ColorReset)
utils.Command("chrt -p 1234", "показать политику процесса")
utils.Command("chrt -f -p 50 1234", "установить FIFO с приоритетом 50")
utils.Command("chrt -r 1234", "установить Round-Robin")
utils.Command("chrt -o -p 0 1234", "обычная политика (SCHED_OTHER)")
utils.Command("chrt -f 50 ./myapp", "запустить с FIFO приоритетом 50")
fmt.Println()
utils.Println(utils.ColorBold + "Просмотр загрузки CPU:" + utils.ColorReset)
utils.Command("mpstat 1 5", "загрузка каждого CPU (пакет sysstat)")
utils.Command("mpstat -P ALL 1", "все ядра каждую секунду")
utils.Command("iostat -x 1", "статистика I/O дисков")
utils.Command("sar -u 1 10", "средняя загрузка CPU 10 раз по 1 сек")
utils.Command("perf top", "top по использованию CPU (нужен perf)")
utils.Code(`# cpupower управление частотой CPU:
cpupower frequency-info # текущий режим
cpupower frequency-set -g performance # режим производительности
# governors: performance, powersave, ondemand, conservative`)
// ─── 51. tuned ────────────────────────────────────────────────
utils.Section("51. Оптимизация производительности — tuned")
utils.Println("tuned — демон автоматической оптимизации системы по профилям.")
utils.Println("Настраивает CPU, диски, сеть под конкретные сценарии использования.")
fmt.Println()
utils.Println(utils.ColorBold + "Управление tuned:" + utils.ColorReset)
utils.Command("systemctl status tuned", "статус демона")
utils.Command("tuned-adm active", "текущий профиль")
utils.Command("tuned-adm list", "список доступных профилей")
utils.Command("tuned-adm profile throughput-performance", "применить профиль")
utils.Command("tuned-adm recommend", "рекомендованный профиль для этой системы")
utils.Command("tuned-adm off", "отключить tuned")
fmt.Println()
utils.Println(utils.ColorBold + "Встроенные профили:" + utils.ColorReset)
utils.Code(`balanced баланс производительности и энергопотребления
powersave минимальное энергопотребление
throughput-performance максимальная пропускная способность (серверы)
latency-performance минимальная задержка (без энергосбережения)
network-latency минимальная сетевая задержка
network-throughput максимальная сетевая пропускная способность
virtual-guest оптимизация для виртуальных машин
virtual-host оптимизация для хоста виртуализации
oracle для Oracle DB
mssql для MS SQL Server
desktop для рабочих станций`)
utils.Println(utils.ColorBold + "Создание собственного профиля:" + utils.ColorReset)
utils.Code(`# Профили хранятся в /usr/lib/tuned/ (системные)
# и /etc/tuned/ (пользовательские)
# Создать профиль на основе существующего:
mkdir /etc/tuned/myprofile
cat > /etc/tuned/myprofile/tuned.conf << 'EOF'
[main]
summary=Мой профиль
include=throughput-performance
[cpu]
governor=performance
energy_perf_bias=performance
[disk]
readahead=>4096
[sysctl]
vm.swappiness=10
net.core.somaxconn=65535
EOF
tuned-adm profile myprofile`)
// ─── 52. Stratis ──────────────────────────────────────────────
utils.Section("52. Управление многоуровневым хранилищем — Stratis")
utils.Println("Stratis — менеджер хранилища от Red Hat (RHEL 8+).")
utils.Println("Упрощает создание пулов, снапшотов и тонкого выделения места.")
utils.Println("Работает поверх LVM и XFS.")
fmt.Println()
utils.Code(`Архитектура Stratis:
Physical Device (/dev/sdb, /dev/sdc)
Pool (пул хранилища)
Filesystem (XFS файловая система)
Особенности:
- Тонкое выделение (thin provisioning)
- Снапшоты (моментальные снимки)
- Кэширование (SSD как кэш для HDD)
- Автоматическое управление XFS`)
utils.Println(utils.ColorBold + "Установка и запуск:" + utils.ColorReset)
utils.Code(`# RHEL/Fedora:
dnf install stratisd stratis-cli
systemctl enable --now stratisd`)
utils.Println(utils.ColorBold + "Работа с пулами:" + utils.ColorReset)
utils.Code(`# Создать пул:
stratis pool create mypool /dev/sdb
stratis pool create mypool /dev/sdb /dev/sdc # из нескольких дисков
# Добавить диск в существующий пул:
stratis pool add-data mypool /dev/sdd
# Добавить кэш (SSD):
stratis pool add-cache mypool /dev/nvme0n1
# Список пулов:
stratis pool list
# Детали пула:
stratis pool info mypool`)
utils.Println(utils.ColorBold + "Работа с файловыми системами:" + utils.ColorReset)
utils.Code(`# Создать ФС в пуле:
stratis filesystem create mypool myfs
# Список ФС:
stratis filesystem list
stratis fs
# Монтирование:
mount /stratis/mypool/myfs /mnt/data
# В /etc/fstab (с x-systemd.requires):
/stratis/mypool/myfs /mnt/data xfs defaults,x-systemd.requires=stratisd.service 0 0
# Создать снапшот:
stratis filesystem snapshot mypool myfs myfs-snapshot
# Удалить ФС:
stratis filesystem destroy mypool myfs
# Удалить пул (сначала удалить все ФС):
stratis pool destroy mypool`)
utils.Note("Stratis автоматически форматирует дискипод XFS. Не используйте mkfs вручную.")
utils.Note("Снапшоты — это отдельные ФС. Можно смонтировать для восстановления файлов.")
utils.Footer()
}

View file

@ -0,0 +1,207 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var ProcessesModule = Module{
Key: "processes",
Aliases: []string{"proc", "ps", "процессы"},
Title: "Процессы",
Description: "Темы 1416: информация о процессах, сигналы, управление процессами",
Run: showProcesses,
}
func showProcesses() {
utils.Header("Linux — Процессы")
// ─── 14. Процессы №1: информация ─────────────────────────────
utils.Section("14. Процессы №1: информация о процессах")
utils.Println("Процесс — выполняющаяся программа. Каждый процесс имеет уникальный PID.")
fmt.Println()
utils.Println(utils.ColorBold + "ps — информация о процессах:" + utils.ColorReset)
utils.Command("ps", "процессы текущего терминала")
utils.Command("ps aux", "все процессы всех пользователей (BSD стиль)")
utils.Command("ps -ef", "все процессы (UNIX стиль)")
utils.Command("ps aux | grep nginx", "найти процессы nginx")
utils.Command("ps -u alice", "процессы пользователя alice")
utils.Command("ps --forest", "дерево процессов (родитель → потомок)")
fmt.Println()
utils.Code(`# Вывод ps aux:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 168384 13312 ? Ss Jan01 0:05 /sbin/init
alice 1234 2.1 1.5 567890 61234 pts/0 Sl 10:30 0:12 firefox
Поля:
USER владелец процесса
PID Process ID (уникальный номер)
PPID Parent PID (родительский процесс)
%CPU использование процессора
%MEM использование памяти
VSZ виртуальная память (КБ)
RSS реальная память (КБ)
TTY терминал (? = нет терминала, демон)
STAT состояние процесса
START время запуска
TIME суммарное CPU-время
COMMAND команда
Коды состояния (STAT):
R Running (работает)
S Sleeping (ожидает, прерываемый)
D Sleeping (ожидает, непрерываемый, I/O)
Z Zombie (завершён, ждёт родителя)
T Stopped (остановлен сигналом)
s лидер сессии
+ процесс переднего плана
l многопоточный`)
utils.Println(utils.ColorBold + "pstree — дерево процессов:" + utils.ColorReset)
utils.Command("pstree", "дерево всех процессов")
utils.Command("pstree -p", "с PID")
utils.Command("pstree alice", "только процессы пользователя alice")
fmt.Println()
utils.Println(utils.ColorBold + "/proc — виртуальная файловая система:" + utils.ColorReset)
utils.Code(`/proc информация о процессах и ядре
/proc/PID/ директория конкретного процесса
/proc/PID/cmdline командная строка запуска
/proc/PID/status статус процесса (память, UID...)
/proc/PID/fd/ открытые файловые дескрипторы
/proc/PID/maps карта памяти процесса
/proc/cpuinfo информация о CPU
/proc/meminfo информация о памяти
/proc/loadavg средняя загрузка
# Примеры:
cat /proc/1/cmdline # команда процесса PID=1
cat /proc/cpuinfo | grep "model name"
cat /proc/meminfo | grep MemAvail`)
// ─── 15. Процессы №2: информация ─────────────────────────────
utils.Section("15. Процессы №2: мониторинг в реальном времени")
utils.Println(utils.ColorBold + "top — динамический мониторинг:" + utils.ColorReset)
utils.Command("top", "интерактивный мониторинг (обновляется каждые 3 сек)")
utils.Command("top -u alice", "только процессы пользователя alice")
utils.Command("top -p 1234,5678", "только указанные PID")
utils.Command("top -b -n 1", "пакетный режим (для скриптов/логирования)")
fmt.Println()
utils.Code(`Клавиши в top:
q выйти
h справка
k убить процесс (ввести PID)
r изменить nice (приоритет)
M сортировать по памяти
P сортировать по CPU
T сортировать по времени
1 показать каждый CPU отдельно
f настройка столбцов
u фильтр по пользователю`)
utils.Println(utils.ColorBold + "htop — улучшенный top (нужно установить):" + utils.ColorReset)
utils.Command("htop", "цветной интерактивный мониторинг")
utils.Code(`# Установка:
apt install htop # Debian/Ubuntu
dnf install htop # RHEL/Fedora`)
utils.Println(utils.ColorBold + "Мониторинг ресурсов:" + utils.ColorReset)
utils.Command("free -h", "использование памяти (human-readable)")
utils.Command("free -m", "в мегабайтах")
utils.Command("vmstat 2 5", "статистика памяти, CPU каждые 2 сек, 5 раз")
utils.Command("uptime", "время работы системы и средняя загрузка")
utils.Command("w", "кто залогинен и что делает")
utils.Command("who", "список залогиненных пользователей")
utils.Command("last", "история входов в систему")
fmt.Println()
utils.Code(`# Средняя загрузка (load average):
uptime
# 10:30:00 up 5 days, 2:15, 2 users, load average: 0.52, 0.41, 0.35
# 1min 5min 15min
# Значение = количество процессов ждущих CPU
# На однопроцессорной системе:
# < 1.0 нормально
# = 1.0 100% загрузка
# > 1.0 перегрузка (очередь)
# На N ядрах перегрузка начинается при load > N`)
utils.Println(utils.ColorBold + "lsof — открытые файлы и соединения:" + utils.ColorReset)
utils.Command("lsof", "все открытые файлы (очень много)")
utils.Command("lsof -p 1234", "открытые файлы процесса 1234")
utils.Command("lsof -u alice", "файлы пользователя alice")
utils.Command("lsof -i :80", "что использует порт 80")
utils.Command("lsof -i TCP", "все TCP соединения")
utils.Command("lsof /var/log/syslog", "какие процессы используют этот файл")
// ─── 16. Процессы №3: управление ─────────────────────────────
utils.Section("16. Процессы №3: управление процессами")
utils.Println(utils.ColorBold + "Сигналы:" + utils.ColorReset)
utils.Code(`Сигнал асинхронное уведомление процессу.
Номер Имя Действие по умолчанию
1 SIGHUP Завершить (или перечитать конфиг для демонов)
2 SIGINT Прервать (Ctrl+C)
3 SIGQUIT Завершить с core dump (Ctrl+\)
9 SIGKILL Убить немедленно (нельзя перехватить/игнорировать)
15 SIGTERM Завершить корректно (по умолчанию для kill)
17 SIGCHLD Дочерний процесс изменил состояние
18 SIGCONT Продолжить остановленный процесс
19 SIGSTOP Остановить (нельзя перехватить/игнорировать)
20 SIGTSTP Остановить (Ctrl+Z, можно перехватить)`)
utils.Println(utils.ColorBold + "kill — отправить сигнал процессу:" + utils.ColorReset)
utils.Command("kill 1234", "SIGTERM (15) процессу 1234 — корректное завершение")
utils.Command("kill -9 1234", "SIGKILL — принудительное убийство")
utils.Command("kill -15 1234", "SIGTERM явно")
utils.Command("kill -HUP 1234", "SIGHUP (перечитать конфиг)")
utils.Command("kill -l", "список всех сигналов")
utils.Command("killall nginx", "SIGTERM всем процессам с именем nginx")
utils.Command("killall -9 nginx", "SIGKILL всем nginx")
utils.Command("pkill nginx", "SIGTERM по имени (поддерживает regex)")
utils.Command("pkill -u alice", "завершить все процессы пользователя alice")
fmt.Println()
utils.Note("Сначала используйте kill (SIGTERM) — даёт процессу завершиться корректно. SIGKILL только если SIGTERM не помог.")
utils.Println(utils.ColorBold + "Приоритет процессов (nice):" + utils.ColorReset)
utils.Code(`Nice значение: от -20 (максимальный приоритет) до 19 (минимальный)
По умолчанию: 0
# Запустить с пониженным приоритетом:
nice -n 10 make -j4
# Изменить приоритет запущенного процесса:
renice -n 5 -p 1234 # PID
renice -n 5 -u alice # для пользователя
# renice на отрицательное значение требует root`)
utils.Println(utils.ColorBold + "Фоновые процессы и задания (job control):" + utils.ColorReset)
utils.Code(`# Запустить в фоне:
command & # & в конце
long_task.sh &
# Управление заданиями:
jobs # список фоновых заданий текущего терминала
jobs -l # с PID
fg # вернуть последнее задание на передний план
fg %2 # вернуть задание 2
bg # продолжить остановленное в фоне
bg %1 # продолжить задание 1 в фоне
# Ctrl+Z приостановить текущий процесс (SIGTSTP)
# Затем bg продолжить в фоне
# Процесс продолжит работу после выхода из терминала:
nohup command & # игнорировать SIGHUP при выходе
disown %1 # отвязать задание от терминала`)
utils.Println(utils.ColorBold + "watch — периодически выполнять команду:" + utils.ColorReset)
utils.Command("watch -n 2 'ps aux | grep nginx'", "каждые 2 сек смотреть процессы nginx")
utils.Command("watch -d free -h", "следить за памятью, выделять изменения")
utils.Command("watch -n 1 uptime", "загрузка каждую секунду")
utils.Footer()
}

View file

@ -0,0 +1,69 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
"strings"
)
// Module описывает один раздел справочника Linux
type Module struct {
Key string
Aliases []string
Title string
Description string
Run func()
}
// All — список всех модулей в порядке меню
var All = []Module{
IntroModule,
FilesModule,
StreamsModule,
BashModule,
ProcessesModule,
UsersModule,
KernelModule,
DisksModule,
ScriptsModule,
BootModule,
LogsModule,
BackupModule,
NetworkModule,
SecurityModule,
PackagesModule,
PerformanceModule,
SysconfigModule,
NetfsModule,
ToolsModule,
}
// Find ищет модуль по ключу или алиасу
func Find(key string) (Module, bool) {
key = strings.ToLower(strings.TrimSpace(key))
for _, m := range All {
if m.Key == key {
return m, true
}
for _, a := range m.Aliases {
if a == key {
return m, true
}
}
}
return Module{}, false
}
// ListModules выводит краткий список модулей
func ListModules() {
fmt.Printf("\n%s%sРазделы справочника Linux:%s\n\n",
utils.ColorBold, utils.ColorCyan, utils.ColorReset)
for i, m := range All {
fmt.Printf(" %s%d.%s %-12s — %s\n",
utils.ColorDim, i+1, utils.ColorReset,
utils.ColorYellow+utils.ColorBold+m.Key+utils.ColorReset,
m.Title,
)
}
fmt.Println()
}

View file

@ -0,0 +1,318 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var ScriptsModule = Module{
Key: "scripts",
Aliases: []string{"sc", "scripting", "скрипты"},
Title: "Bash-скрипты",
Description: "Темы 2732: скрипты, условия, циклы, функции, массивы",
Run: showScripts,
}
func showScripts() {
utils.Header("Linux — Bash-скрипты")
// ─── 27. Bash скрипты №1 ──────────────────────────────────────
utils.Section("27. Основы скриптов. Условия")
utils.Println(utils.ColorBold + "Структура скрипта:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Shebang первая строка указывает интерпретатор
# Комментарий
echo "Привет, мир!"
# Запуск скрипта:
chmod +x script.sh # сделать исполняемым
./script.sh # запустить
bash script.sh # запустить через bash (без chmod)`)
utils.Println(utils.ColorBold + "Переменные в скриптах:" + utils.ColorReset)
utils.Code(`#!/bin/bash
name="Alice"
count=5
echo "Имя: $name"
echo "Счёт: $count"
# Ввод от пользователя:
read -p "Введите имя: " username
echo "Привет, $username!"
# Ввод без отображения (пароль):
read -s -p "Пароль: " password`)
utils.Println(utils.ColorBold + "Условный оператор if:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Базовая форма:
if [ условие ]; then
команды
elif [ другое_условие ]; then
команды
else
команды
fi
# Примеры условий:
# Сравнение строк:
if [ "$name" = "Alice" ]; then echo "Привет, Alice"; fi
if [ "$name" != "Bob" ]; then echo "Не Боб"; fi
if [ -z "$name" ]; then echo "Пустая строка"; fi # -z = пусто
if [ -n "$name" ]; then echo "Не пустая"; fi # -n = не пусто
# Сравнение чисел:
if [ "$count" -eq 5 ]; then ... # equal
if [ "$count" -ne 5 ]; then ... # not equal
if [ "$count" -gt 3 ]; then ... # greater than
if [ "$count" -lt 10 ]; then ... # less than
if [ "$count" -ge 5 ]; then ... # greater or equal
if [ "$count" -le 5 ]; then ... # less or equal
# Файлы и директории:
if [ -f /etc/passwd ]; then echo "файл существует"; fi
if [ -d /tmp ]; then echo "директория существует"; fi
if [ -e /dev/sda ]; then echo "путь существует"; fi
if [ -r file ]; then echo "доступен для чтения"; fi
if [ -w file ]; then echo "доступен для записи"; fi
if [ -x script.sh ]; then echo "исполняемый"; fi
if [ -s file ]; then echo "файл не пустой"; fi
if [ file1 -nt file2 ]; then echo "file1 новее"; fi
# Логика:
if [ cond1 ] && [ cond2 ]; then ... # И
if [ cond1 ] || [ cond2 ]; then ... # ИЛИ
if ! [ cond ]; then ... # НЕ
# [[ ]] расширенные условия bash:
if [[ "$str" == *"подстрока"* ]]; then ... # glob
if [[ "$str" =~ ^[0-9]+$ ]]; then ... # regex`)
// ─── 2829. Bash скрипты №23 ─────────────────────────────────
utils.Section("2829. Циклы")
utils.Println(utils.ColorBold + "Цикл for:" + utils.ColorReset)
utils.Code(`# По списку:
for item in один два три; do
echo "$item"
done
# По числовому диапазону:
for i in {1..5}; do
echo "Шаг $i"
done
# С шагом:
for i in {0..20..5}; do echo "$i"; done # 0 5 10 15 20
# C-стиль:
for ((i=0; i<5; i++)); do
echo "$i"
done
# По файлам:
for file in /etc/*.conf; do
echo "Обрабатываю: $file"
done
# По строкам вывода команды:
for user in $(cat /etc/passwd | cut -d: -f1); do
echo "Пользователь: $user"
done`)
utils.Println(utils.ColorBold + "Цикл while:" + utils.ColorReset)
utils.Code(`# Пока условие истинно:
count=0
while [ $count -lt 5 ]; do
echo "count = $count"
((count++))
done
# Чтение файла построчно:
while IFS= read -r line; do
echo "Строка: $line"
done < /etc/hosts
# Бесконечный цикл:
while true; do
echo "Работаю..."
sleep 1
done`)
utils.Println(utils.ColorBold + "Цикл until и управление циклами:" + utils.ColorReset)
utils.Code(`# Пока условие ложно:
until [ -f /tmp/ready ]; do
echo "Жду файл..."
sleep 1
done
# break выйти из цикла:
for i in {1..10}; do
if [ $i -eq 5 ]; then break; fi
echo $i
done
# continue перейти к следующей итерации:
for i in {1..10}; do
if [ $((i % 2)) -eq 0 ]; then continue; fi
echo "Нечётное: $i"
done`)
// ─── 3031. Bash скрипты №45 ─────────────────────────────────
utils.Section("3031. Функции и обработка ошибок")
utils.Println(utils.ColorBold + "Функции:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Объявление функции:
greet() {
local name=$1 # local локальная переменная
echo "Привет, $name!"
}
# Или:
function greet {
echo "Привет, $1!"
}
# Вызов:
greet "Alice"
greet "Bob"
# Возвращаемое значение:
# Функции возвращают только числа (код возврата 0-255)
is_root() {
[ "$(id -u)" -eq 0 ]
}
if is_root; then
echo "Запущен как root"
fi
# Для передачи строк echo + подстановка команд:
get_hostname() {
echo "$(hostname)"
}
host=$(get_hostname)`)
utils.Println(utils.ColorBold + "Обработка ошибок:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Остановить при ошибке:
set -e # выйти при любой ошибке (exit on error)
set -u # ошибка при неопределённой переменной
set -o pipefail # учитывать ошибки в pipe
set -euo pipefail # всё вместе (рекомендуется)
# Проверка кода возврата:
if ! mkdir /tmp/mydir 2>/dev/null; then
echo "Ошибка создания директории" >&2
exit 1
fi
# Функция для вывода ошибок:
error() {
echo "ОШИБКА: $*" >&2
exit 1
}
[ -f "$1" ] || error "Файл $1 не найден"
# Trap обработка сигналов и выхода:
cleanup() {
rm -f /tmp/tempfile
echo "Очищено"
}
trap cleanup EXIT # при любом выходе
trap cleanup INT TERM # при Ctrl+C или kill`)
// ─── 32. Bash скрипты №6 ──────────────────────────────────────
utils.Section("32. Массивы, строки и аргументы скрипта")
utils.Println(utils.ColorBold + "Массивы:" + utils.ColorReset)
utils.Code(`# Объявление:
fruits=("яблоко" "банан" "апельсин")
declare -a numbers=(1 2 3 4 5)
# Доступ:
echo "${fruits[0]}" # яблоко (индекс с 0)
echo "${fruits[@]}" # все элементы
echo "${#fruits[@]}" # количество элементов
echo "${fruits[@]:1:2}" # срез: с индекса 1, 2 элемента
# Добавить элемент:
fruits+=("манго")
# Перебор:
for fruit in "${fruits[@]}"; do
echo "$fruit"
done
# Перебор с индексом:
for i in "${!fruits[@]}"; do
echo "$i: ${fruits[$i]}"
done
# Ассоциативный массив (словарь):
declare -A user
user[name]="Alice"
user[age]=30
echo "${user[name]}"
echo "${!user[@]}" # ключи
echo "${user[@]}" # значения`)
utils.Println(utils.ColorBold + "Аргументы скрипта:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Позиционные параметры:
echo "Скрипт: $0"
echo "Первый аргумент: $1"
echo "Второй аргумент: $2"
echo "Все аргументы: $@"
echo "Количество аргументов: $#"
# Проверка аргументов:
if [ $# -lt 2 ]; then
echo "Использование: $0 <имя> <возраст>" >&2
exit 1
fi
# Обработка опций (getopts):
while getopts "hv:n:" opt; do
case $opt in
h) echo "Справка"; exit 0 ;;
v) verbose=true ;;
n) name="$OPTARG" ;;
?) echo "Неизвестный ключ"; exit 1 ;;
esac
done
# shift сдвинуть аргументы:
shift $((OPTIND - 1)) # убрать опции, остались обычные аргументы`)
utils.Println(utils.ColorBold + "Полезные приёмы:" + utils.ColorReset)
utils.Code(`# Цвета в терминале:
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
echo -e "${RED}Ошибка${NC}"
echo -e "${GREEN}Успех${NC}"
# Прогресс-бар простой:
for i in {1..10}; do
echo -ne "\rПрогресс: $((i*10))%"
sleep 0.1
done; echo
# Логирование:
LOG=/var/log/myscript.log
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }
log "Скрипт запущен"
# Ожидание с таймаутом:
timeout 30 ./long_command.sh || echo "Таймаут!"`)
fmt.Println()
utils.Note("Проверяйте скрипты на ошибки: bash -n script.sh (синтаксис) и bash -x script.sh (трассировка).")
utils.Footer()
}

View file

@ -0,0 +1,276 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var SecurityModule = Module{
Key: "security",
Aliases: []string{"sec", "selinux", "firewall", "безопасность"},
Title: "Безопасность: SELinux и Firewall",
Description: "Темы 4546, 48: SELinux, firewalld, восстановление доступа",
Run: showSecurity,
}
func showSecurity() {
utils.Header("Linux — Безопасность: SELinux и Firewall")
// ─── 45. SELinux ──────────────────────────────────────────────
utils.Section("45. Принудительный контроль доступа — SELinux")
utils.Println("SELinux (Security-Enhanced Linux) — система принудительного контроля доступа.")
utils.Println("Работает поверх обычных прав Unix: даже root ограничен политикой SELinux.")
fmt.Println()
utils.Println(utils.ColorBold + "Режимы SELinux:" + utils.ColorReset)
utils.Code(`Enforcing SELinux активен, запрещённые действия блокируются
и логируются (производственный режим)
Permissive SELinux активен, нарушения только логируются
(не блокируются). Для отладки.
Disabled SELinux полностью отключён (требует перезагрузки)
# Текущий режим:
getenforce
sestatus # подробная информация
# Временно изменить режим (до перезагрузки):
setenforce 0 # Enforcing Permissive
setenforce 1 # Permissive Enforcing
setenforce Permissive # то же самое
# Постоянно /etc/selinux/config:
SELINUX=enforcing # enforcing / permissive / disabled
SELINUXTYPE=targeted # политика
# После изменения с/на disabled нужна перезагрузка.
# При включении SELinux после disabled нужна переметка файлов:
touch /.autorelabel && reboot`)
utils.Println(utils.ColorBold + "Контексты SELinux:" + utils.ColorReset)
utils.Code(`Каждый файл, процесс и порт имеет SELinux-контекст:
user:role:type:level
system_u:object_r:httpd_sys_content_t:s0
Самое важное type (тип): httpd_sys_content_t, etc_t...
# Просмотр контекстов файлов:
ls -Z /var/www/html/
ls -lZ /etc/nginx/
# Просмотр контекста процессов:
ps auxZ | grep nginx
# Просмотр контекста портов:
semanage port -l | grep http`)
utils.Println(utils.ColorBold + "Управление контекстами:" + utils.ColorReset)
utils.Code(`# Изменить контекст файла:
chcon -t httpd_sys_content_t /var/www/mysite/
chcon -R -t httpd_sys_content_t /var/www/mysite/ # рекурсивно
# Проблема: chcon не постоянен, restorecon сбросит его.
# Правильно: использовать semanage fcontext:
# Добавить постоянное правило для контекста:
semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'
# Применить правила к файлам:
restorecon -Rv /srv/web/
# Восстановить контекст по умолчанию:
restorecon -Rv /var/www/html/
# Проверить ожидаемый контекст:
matchpathcon /var/www/html/index.html`)
utils.Println(utils.ColorBold + "Булевые переменные SELinux (Booleans):" + utils.ColorReset)
utils.Code(`# Booleans включают/выключают определённые возможности:
# Просмотр всех:
getsebool -a
getsebool -a | grep httpd
# Включить/выключить (временно):
setsebool httpd_can_network_connect on
setsebool httpd_can_network_connect off
# Постоянно (после перезагрузки):
setsebool -P httpd_can_network_connect on
setsebool -P httpd_enable_homedirs on
# Полезные booleans:
httpd_can_network_connect # nginx/apache внешняя сеть
httpd_can_network_connect_db # nginx/apache БД
httpd_enable_homedirs # доступ к /home
samba_enable_home_dirs # Samba к /home
ssh_sysadm_login # SSH-вход для sysadmin`)
utils.Println(utils.ColorBold + "Порты и SELinux:" + utils.ColorReset)
utils.Code(`# Посмотреть разрешённые порты:
semanage port -l
semanage port -l | grep http
# Разрешить nginx слушать нестандартный порт 8888:
semanage port -a -t http_port_t -p tcp 8888
# Удалить правило порта:
semanage port -d -t http_port_t -p tcp 8888
# Изменить существующее правило:
semanage port -m -t http_port_t -p tcp 8888`)
utils.Println(utils.ColorBold + "Диагностика проблем SELinux:" + utils.ColorReset)
utils.Code(`# Логи SELinux:
/var/log/audit/audit.log # основной лог
# Поиск запретов:
ausearch -m avc -ts recent # последние запреты AVC
grep 'denied' /var/log/audit/audit.log | tail -20
# audit2why объяснить запрет:
ausearch -m avc -ts recent | audit2why
# audit2allow создать модуль для разрешения:
ausearch -m avc -ts recent | audit2allow -m mymodule > mymodule.te
checkmodule -M -m -o mymodule.mod mymodule.te
semodule_package -o mymodule.pp -m mymodule.mod
semodule -i mymodule.pp
# sealert графическая диагностика (если установлен setroubleshoot):
sealert -a /var/log/audit/audit.log`)
// ─── 46. firewalld ────────────────────────────────────────────
utils.Section("46. Межсетевой экран — firewalld")
utils.Println("firewalld — динамический менеджер firewall в RHEL/Fedora/CentOS.")
utils.Println("Работает поверх nftables (или iptables).")
fmt.Println()
utils.Println(utils.ColorBold + "Зоны (Zones) — основное понятие firewalld:" + utils.ColorReset)
utils.Code(`Зона определяет уровень доверия к трафику интерфейса.
drop всё входящее молча отбрасывается
block входящее отклоняется с сообщением об ошибке
public публичные сети, только явно разрешённое (по умолчанию)
external внешние сети с маскарадингом
internal внутренние сети, больше доверие
home домашние сети
work рабочие сети
dmz демилитаризованная зона
trusted весь трафик разрешён`)
utils.Println(utils.ColorBold + "Основные команды firewall-cmd:" + utils.ColorReset)
utils.Command("firewall-cmd --state", "работает ли firewalld")
utils.Command("systemctl status firewalld", "статус сервиса")
utils.Command("firewall-cmd --get-active-zones", "активные зоны и интерфейсы")
utils.Command("firewall-cmd --get-default-zone", "зона по умолчанию")
utils.Command("firewall-cmd --list-all", "все правила активной зоны")
utils.Command("firewall-cmd --list-all --zone=public", "правила зоны public")
fmt.Println()
utils.Println(utils.ColorBold + "Управление сервисами и портами:" + utils.ColorReset)
utils.Code(`# Разрешить сервис (временно, до перезагрузки):
firewall-cmd --add-service=http
firewall-cmd --add-service=https
firewall-cmd --add-service=ssh
# Постоянно (--permanent):
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload # применить permanent-правила
# Удалить сервис:
firewall-cmd --permanent --remove-service=http
# Список доступных сервисов:
firewall-cmd --get-services
# Разрешить порт напрямую:
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --permanent --add-port=5000-5100/tcp
firewall-cmd --permanent --remove-port=8080/tcp`)
utils.Println(utils.ColorBold + "Rich rules — сложные правила:" + utils.ColorReset)
utils.Code(`# Разрешить SSH только с конкретного IP:
firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="192.168.1.0/24"
service name="ssh" accept'
# Заблокировать IP:
firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="10.10.10.5"
drop'
# Ограничить количество соединений (rate limiting):
firewall-cmd --permanent --add-rich-rule='
rule service name="ssh"
limit value="5/m" accept'`)
utils.Println(utils.ColorBold + "Маскарадинг (NAT):" + utils.ColorReset)
utils.Code(`# Включить маскарадинг (нужно для роутера):
firewall-cmd --permanent --zone=external --add-masquerade
# Пробросить порт:
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
# Внешний 80 внутренний 8080`)
// ─── 48. Восстановление доступа ───────────────────────────────
utils.Section("48. Восстановление доступа")
utils.Println("Что делать если потеряли пароль root или доступ к системе.")
fmt.Println()
utils.Println(utils.ColorBold + "Сброс пароля root (RHEL/CentOS):" + utils.ColorReset)
utils.Code(`1. Перезагрузить систему.
2. В меню GRUB нажать 'e' на нужной записи.
3. Найти строку начинающуюся с linux или linuxefi.
4. В конце строки добавить: rd.break
5. Нажать Ctrl+X для загрузки.
# В initramfs shell:
mount -o remount,rw /sysroot # перемонтировать с правами записи
chroot /sysroot # перейти в систему
passwd root # задать новый пароль root
# Если SELinux включён:
touch /.autorelabel # переметить файлы SELinux
exit
reboot`)
utils.Println(utils.ColorBold + "Сброс пароля root (Ubuntu/Debian):" + utils.ColorReset)
utils.Code(`1. В GRUB выбрать "Advanced options".
2. Выбрать строку "(recovery mode)".
3. В меню recovery выбрать "root".
# Или: в GRUB нажать 'e', найти строку linux,
# заменить ro на rw, добавить в конец: init=/bin/bash
# В shell:
passwd root
# Если файловая система только для чтения:
mount -o remount,rw /
passwd root
sync
reboot -f`)
utils.Println(utils.ColorBold + "Восстановление из LiveCD:" + utils.ColorReset)
utils.Code(`# Загрузиться с LiveCD/LiveUSB
# Найти системный раздел:
lsblk
# Смонтировать:
mount /dev/sda2 /mnt
mount /dev/sda1 /mnt/boot # boot раздел
# Для UEFI:
mount /dev/sda1 /mnt/boot/efi
# Chroot:
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
chroot /mnt
# Теперь можно: passwd root, grub-install, etc.`)
utils.Footer()
}

View file

@ -0,0 +1,135 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var StreamsModule = Module{
Key: "streams",
Aliases: []string{"st", "io", "потоки"},
Title: "Стандартные потоки и перенаправление",
Description: "Тема 11: stdin, stdout, stderr, перенаправление, pipe",
Run: showStreams,
}
func showStreams() {
utils.Header("Linux — Стандартные потоки и перенаправление")
// ─── 11. Стандартные потоки ───────────────────────────────────
utils.Section("11. Стандартные потоки (Standard Streams)")
utils.Println("Каждый процесс в Linux имеет три стандартных потока ввода-вывода:")
fmt.Println()
utils.Code(`Дескриптор Имя Поток По умолчанию
0 stdin ввод клавиатура
1 stdout вывод терминал
2 stderr вывод ошибок терминал
Программа читает из stdin, пишет результат в stdout,
ошибки в stderr.`)
utils.Println(utils.ColorBold + "Перенаправление вывода (stdout):" + utils.ColorReset)
utils.Code(`> перенаправить stdout в файл (перезаписать)
>> перенаправить stdout в файл (дописать в конец)
ls /etc > list.txt # список файлов файл
echo "строка" >> log.txt # дописать в конец
date > /dev/null # выбросить вывод в никуда`)
utils.Println(utils.ColorBold + "Перенаправление ошибок (stderr):" + utils.ColorReset)
utils.Code(`2> перенаправить stderr в файл
2>> дописать stderr в файл
2>&1 направить stderr туда же куда stdout
ls /nonexistent 2> errors.txt # ошибки файл
ls /etc 1> out.txt 2> err.txt # каждый поток отдельно
ls /etc /nonexistent > all.txt 2>&1 # всё в один файл
ls /etc /nonexistent &> all.txt # краткая форма bash
ls /etc /nonexistent 2>/dev/null # подавить ошибки`)
utils.Println(utils.ColorBold + "Перенаправление ввода (stdin):" + utils.ColorReset)
utils.Code(`< читать stdin из файла
sort < unsorted.txt # отсортировать содержимое файла
wc -l < file.txt # считать строки из файла
# Here-document передать несколько строк:
cat << EOF
строка 1
строка 2
EOF
# Here-string передать строку:
grep 'pattern' <<< "одна строка для поиска"`)
utils.Println(utils.ColorBold + "Конвейер (pipe) |:" + utils.ColorReset)
utils.Println("Pipe передаёт stdout одной команды в stdin следующей.")
utils.Code(`ls -la | grep '.conf' # только .conf файлы
cat /etc/passwd | sort # отсортировать passwd
ps aux | grep nginx # найти процессы nginx
cat file.txt | wc -l # посчитать строки
ls /etc | head -10 # первые 10 строк
history | tail -20 | grep git # цепочка из трёх команд`)
utils.Println(utils.ColorBold + "tee — записать и передать дальше:" + utils.ColorReset)
utils.Code(`# tee читает stdin, пишет в файл И в stdout:
ls -la | tee listing.txt | grep '.conf'
# -a дописать в файл (append):
echo "строка" | tee -a log.txt`)
utils.Println(utils.ColorBold + "xargs — передать строки как аргументы:" + utils.ColorReset)
utils.Code(`# find возвращает список файлов, xargs передаёт их rm:
find /tmp -name '*.tmp' | xargs rm -f
# -I{} подстановка каждой строки в {}:
cat hosts.txt | xargs -I{} ping -c1 {}
# -P4 параллельно (4 процесса):
cat urls.txt | xargs -P4 -I{} curl -O {}`)
utils.Println(utils.ColorBold + "/dev/null и /dev/zero:" + utils.ColorReset)
utils.Code(`/dev/null "чёрная дыра": запись выбрасывается, чтение EOF
/dev/zero бесконечный источник нулевых байт
/dev/random случайные байты (медленно, использует энтропию)
/dev/urandom псевдослучайные байты (быстро)
# Типичные применения:
command > /dev/null 2>&1 # подавить весь вывод
dd if=/dev/zero of=file bs=1M count=100 # создать 100МБ файл
cat /dev/urandom | head -c 16 | base64 # случайный токен`)
utils.Println(utils.ColorBold + "Подстановка команд (command substitution):" + utils.ColorReset)
utils.Code(`# Результат команды используется как аргумент:
echo "Сегодня: $(date)"
ls -la $(which python3)
mkdir backup_$(date +%Y%m%d)
# Старый стиль (обратные кавычки):
echo "Версия: $(uname -r)" # backtick-форма устарела, используйте $()`)
utils.Println(utils.ColorBold + "Полезные фильтры для pipe:" + utils.ColorReset)
utils.Command("grep", "фильтр строк по паттерну")
utils.Command("sed 's/old/new/g'", "замена текста в потоке")
utils.Command("awk '{print $1}'", "обработка/вывод полей")
utils.Command("sort", "сортировка строк")
utils.Command("uniq", "удаление дубликатов (после sort)")
utils.Command("head -n N", "первые N строк")
utils.Command("tail -n N", "последние N строк")
utils.Command("wc -l", "подсчёт строк")
utils.Command("tr 'a-z' 'A-Z'", "замена символов")
utils.Command("cut -d: -f1", "вырезать поле")
fmt.Println()
utils.Code(`# Практический пример топ-5 процессов по памяти:
ps aux --sort=-%mem | head -6
# Все уникальные IP из лога nginx:
cat /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
# Подсчёт файлов по расширению:
find . -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn`)
utils.Footer()
}

View file

@ -0,0 +1,191 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var SysconfigModule = Module{
Key: "sysconfig",
Aliases: []string{"cfg", "time", "ntp", "chrony", "настройка"},
Title: "Конфигурация системы",
Description: "Темы 5354: установка RHEL, настройка времени, NTP, chronyd",
Run: showSysconfig,
}
func showSysconfig() {
utils.Header("Linux — Конфигурация системы")
// ─── 53. Установка RHEL ───────────────────────────────────────
utils.Section("53. Установка RHEL и первоначальная настройка")
utils.Println("RHEL (Red Hat Enterprise Linux) — коммерческий дистрибутив.")
utils.Println("Бесплатные альтернативы: AlmaLinux, Rocky Linux (1:1 совместимы с RHEL).")
fmt.Println()
utils.Println(utils.ColorBold + "Получение RHEL:" + utils.ColorReset)
utils.Code(`# Бесплатная подписка для разработчиков (до 16 машин):
# https://developers.redhat.com/articles/faqs-no-cost-red-hat-enterprise-linux
# Скачать ISO:
# https://access.redhat.com/downloads
# Альтернативы без подписки:
# AlmaLinux: https://almalinux.org
# Rocky Linux: https://rockylinux.org
# CentOS Stream: https://www.centos.org/centos-stream/`)
utils.Println(utils.ColorBold + "Первоначальная настройка после установки:" + utils.ColorReset)
utils.Code(`# Обновить систему:
dnf update -y
# Настроить hostname:
hostnamectl set-hostname server01.example.com
hostnamectl status
# Настроить часовой пояс:
timedatectl set-timezone Europe/Moscow
# Включить автоматическую синхронизацию времени:
timedatectl set-ntp true
# Добавить репозиторий EPEL (Extra Packages):
dnf install epel-release -y
# или для RHEL:
subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms
# Включить CRB (CodeReady Builder) нужен для некоторых пакетов EPEL:
dnf config-manager --set-enabled crb # RHEL 9
dnf config-manager --set-enabled powertools # RHEL 8`)
utils.Println(utils.ColorBold + "subscription-manager — управление подпиской RHEL:" + utils.ColorReset)
utils.Code(`# Зарегистрировать систему:
subscription-manager register --username=myuser --password=mypass
# Присоединить подписку:
subscription-manager attach --auto
# Список доступных репозиториев:
subscription-manager repos --list
# Включить репозиторий:
subscription-manager repos --enable rhel-9-for-x86_64-baseos-rpms
subscription-manager repos --enable rhel-9-for-x86_64-appstream-rpms
# Отключить регистрацию:
subscription-manager unregister`)
utils.Println(utils.ColorBold + "hostnamectl — управление именем хоста:" + utils.ColorReset)
utils.Command("hostnamectl", "показать всю информацию о хосте")
utils.Command("hostnamectl set-hostname myserver", "установить hostname")
utils.Command("hostnamectl set-hostname 'My Server' --pretty", "красивое имя")
utils.Command("hostname", "показать текущий hostname")
utils.Command("cat /etc/hostname", "hostname из файла")
fmt.Println()
utils.Println(utils.ColorBold + "localectl — настройка локали и раскладки:" + utils.ColorReset)
utils.Command("localectl", "показать текущую локаль")
utils.Command("localectl list-locales | grep ru", "русские локали")
utils.Command("localectl set-locale LANG=ru_RU.UTF-8", "установить русскую локаль")
utils.Command("localectl set-keymap ru", "русская раскладка для консоли")
utils.Command("localectl list-keymaps | grep ru", "доступные раскладки")
// ─── 54. Настройка времени ────────────────────────────────────
utils.Section("54. Настройка времени. NTP и chronyd")
utils.Println(utils.ColorBold + "Типы часов в Linux:" + utils.ColorReset)
utils.Code(`RTC (Hardware Clock) аппаратные часы (BIOS/UEFI), работают без питания
System Clock системные часы ядра, синхронизируются от RTC при загрузке
UTC vs LOCAL:
RTC рекомендуется хранить в UTC, чтобы избежать проблем с летним временем.
Отображение в локальном времени задача ОС.`)
utils.Println(utils.ColorBold + "timedatectl — управление временем:" + utils.ColorReset)
utils.Command("timedatectl", "показать время, часовой пояс, NTP")
utils.Command("timedatectl status", "то же самое")
utils.Command("timedatectl list-timezones", "список часовых поясов")
utils.Command("timedatectl list-timezones | grep Moscow", "найти московский пояс")
utils.Command("timedatectl set-timezone Europe/Moscow", "установить часовой пояс")
utils.Command("timedatectl set-time '2024-01-15 14:30:00'", "установить время вручную")
utils.Command("timedatectl set-ntp true", "включить синхронизацию по NTP")
utils.Command("timedatectl set-ntp false", "отключить NTP")
utils.Command("timedatectl set-local-rtc 0", "хранить RTC в UTC")
fmt.Println()
utils.Println(utils.ColorBold + "hwclock — работа с аппаратными часами:" + utils.ColorReset)
utils.Command("hwclock", "показать время RTC")
utils.Command("hwclock --systohc", "записать системное время в RTC")
utils.Command("hwclock --hctosys", "установить системное время из RTC")
utils.Command("hwclock --utc", "RTC в UTC")
fmt.Println()
utils.Println(utils.ColorBold + "NTP — Network Time Protocol:" + utils.ColorReset)
utils.Code(`NTP протокол синхронизации времени по сети.
Иерархия серверов (stratum):
Stratum 0 атомные часы, GPS
Stratum 1 серверы напрямую подключённые к stratum 0
Stratum 2 синхронизируются от stratum 1
...
Stratum 16 несинхронизированы
Популярные публичные NTP-серверы:
pool.ntp.org пул серверов (рекомендуется)
time.google.com Google
time.cloudflare.com Cloudflare
ntp1.vniiftri.ru Россия (ВНИИФТРИ)
ntp2.vniiftri.ru Россия`)
utils.Println(utils.ColorBold + "chronyd — рекомендуемый NTP-клиент в RHEL:" + utils.ColorReset)
utils.Code(`# Установка (обычно предустановлен):
dnf install chrony # RHEL/Fedora
apt install chrony # Debian/Ubuntu
# Управление:
systemctl enable --now chronyd
systemctl status chronyd`)
utils.Command("chronyc tracking", "статус синхронизации")
utils.Command("chronyc sources", "список NTP-источников")
utils.Command("chronyc sources -v", "подробно")
utils.Command("chronyc sourcestats", "статистика источников")
utils.Command("chronyc makestep", "принудительно синхронизировать (мгновенный шаг)")
utils.Command("chronyc ntpdata", "NTP-данные каждого источника")
fmt.Println()
utils.Println(utils.ColorBold + "Конфигурация chronyd (/etc/chrony.conf):" + utils.ColorReset)
utils.Code(`# Серверы синхронизации:
server pool.ntp.org iburst
server ntp1.vniiftri.ru iburst
server ntp2.vniiftri.ru iburst
pool 2.rhel.pool.ntp.org iburst
# iburst отправлять несколько пакетов при первом контакте (быстрее)
# Разрешить синхронизацию для подсети (NTP-сервер):
allow 192.168.1.0/24
# Синхронизировать RTC с системными часами:
rtcsync
# Сохранять данные о дрейфе:
driftfile /var/lib/chrony/drift
# Принять шаг > 1 сек только при старте:
makestep 1.0 3
# Применить изменения:
systemctl restart chronyd`)
utils.Println(utils.ColorBold + "Настройка chronyd как NTP-сервера для локальной сети:" + utils.ColorReset)
utils.Code(`# /etc/chrony.conf на сервере:
server pool.ntp.org iburst
allow 192.168.1.0/24 # разрешить клиентам из этой подсети
# На клиентах /etc/chrony.conf:
server 192.168.1.10 iburst # указать IP локального NTP-сервера
# Открыть порт на файрволе сервера:
firewall-cmd --permanent --add-service=ntp
firewall-cmd --reload
# Проверить что клиент синхронизирован:
chronyc sources`)
utils.Footer()
}

View file

@ -0,0 +1,252 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var ToolsModule = Module{
Key: "tools",
Aliases: []string{"t", "cockpit", "regex", "awk", "sed", "инструменты"},
Title: "Веб-интерфейс и текстовые инструменты",
Description: "Темы 6061: Cockpit, глоббинг, регулярные выражения, grep, sed, awk",
Run: showTools,
}
func showTools() {
utils.Header("Linux — Веб-интерфейс и текстовые инструменты")
// ─── 60. Cockpit ──────────────────────────────────────────────
utils.Section("60. Веб-интерфейс — Cockpit")
utils.Println("Cockpit — веб-консоль для администрирования Linux через браузер.")
utils.Println("Позволяет управлять сервисами, сетью, дисками, контейнерами и логами.")
fmt.Println()
utils.Println(utils.ColorBold + "Установка и запуск:" + utils.ColorReset)
utils.Code(`# RHEL/Fedora (обычно предустановлен):
dnf install cockpit
systemctl enable --now cockpit.socket
# Ubuntu/Debian:
apt install cockpit
systemctl enable --now cockpit.socket
# Открыть порт в firewalld:
firewall-cmd --permanent --add-service=cockpit
firewall-cmd --reload
# Доступ: https://hostname:9090
# Войти с логином/паролем системного пользователя`)
utils.Println(utils.ColorBold + "Расширения Cockpit:" + utils.ColorReset)
utils.Code(`# Управление виртуальными машинами:
dnf install cockpit-machines
# Управление Podman-контейнерами:
dnf install cockpit-podman
# Управление хранилищем (LVM, RAID, Stratis):
dnf install cockpit-storaged
# 389 DS (LDAP):
dnf install cockpit-389-ds
# Обновления пакетов:
dnf install cockpit-packagekit
# Применить все расширения:
systemctl restart cockpit.socket`)
utils.Println(utils.ColorBold + "Возможности Cockpit:" + utils.ColorReset)
utils.Code(`Dashboard обзор системы: CPU, RAM, диски, сеть
Services управление systemd-сервисами
Storage диски, LVM, RAID, Stratis, NFS
Networking интерфейсы, маршруты, firewall
Accounts пользователи и группы
Software Updates обновление пакетов
Terminal встроенный терминал в браузере
Logs journald логи с фильтрами
Podman управление контейнерами
Machines виртуальные машины (KVM/libvirt)`)
utils.Note("Cockpit работает в браузере, не требует постоянного подключения: сессия = одна вкладка.")
utils.Note("Порт 9090. Сертификат самоподписанный — нужно добавить исключение в браузере или подключить Let's Encrypt.")
// ─── 61. Глоббинг и регулярные выражения ─────────────────────
utils.Section("61. Глоббинг и регулярные выражения")
utils.Println(utils.ColorBold + "Глоббинг (Globbing) — шаблоны оболочки:" + utils.ColorReset)
utils.Code(`* любое количество любых символов (кроме /)
? ровно один любой символ
[abc] один символ из набора
[a-z] один символ из диапазона
[!abc] один символ НЕ из набора
{a,b,c} одно из перечисленных
# Примеры:
ls *.log # все файлы .log
ls file?.txt # file1.txt, fileA.txt...
ls [0-9]*.conf # начинающиеся с цифры
ls /etc/{nginx,apache}* # /etc/nginx* или /etc/apache*
rm backup_{2023,2024}*.tar # удалить бэкапы 2023 и 2024
cp /etc/*.{conf,cfg} /tmp/ # все .conf и .cfg
# Расширенный глоббинг (shopt -s extglob):
?(pattern) 0 или 1 вхождение
*(pattern) 0 или более
+(pattern) 1 или более
@(pattern) ровно 1
!(pattern) всё кроме`)
utils.Println(utils.ColorBold + "Регулярные выражения — базовые (BRE):" + utils.ColorReset)
utils.Code(`. любой символ
* 0 или более предыдущего
^ начало строки
$ конец строки
[abc] один символ из набора
[^abc] один символ НЕ из набора
\(abc\) группа
\{n,m\} от n до m повторений
# Примеры:
grep '^root' /etc/passwd # строки начинающиеся с root
grep 'bash$' /etc/passwd # строки оканчивающиеся на bash
grep '^$' file.txt # пустые строки
grep '[0-9]\{3\}' file.txt # три цифры подряд`)
utils.Println(utils.ColorBold + "Регулярные выражения — расширенные (ERE):" + utils.ColorReset)
utils.Code(`+ 1 или более предыдущего
? 0 или 1 предыдущего
| ИЛИ
(abc) группа (без \)
{n,m} от n до m повторений (без \)
# Использование ERE: grep -E, egrep, sed -E, awk
grep -E 'cat|dog' file.txt # cat или dog
grep -E '^[0-9]+\.' file.txt # строки начинающиеся с числа.
grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' file.txt # IPv4-адрес
grep -E 'error|warning|critical' /var/log/syslog
# Полезные классы символов:
[[:alpha:]] буквы (a-z, A-Z)
[[:digit:]] цифры (0-9)
[[:alnum:]] буквы и цифры
[[:space:]] пробельные символы
[[:upper:]] заглавные буквы
[[:lower:]] строчные буквы
[[:punct:]] знаки препинания`)
utils.Println(utils.ColorBold + "grep — поиск по шаблону:" + utils.ColorReset)
utils.Command("grep 'pattern' file", "базовый поиск")
utils.Command("grep -i 'pattern' file", "без учёта регистра")
utils.Command("grep -v 'pattern' file", "строки НЕ совпадающие")
utils.Command("grep -n 'pattern' file", "с номерами строк")
utils.Command("grep -c 'pattern' file", "количество совпадений")
utils.Command("grep -l 'pattern' *.conf", "только имена файлов")
utils.Command("grep -r 'pattern' /etc/", "рекурсивно в директории")
utils.Command("grep -A 3 'pattern' file", "3 строки ПОСЛЕ совпадения")
utils.Command("grep -B 2 'pattern' file", "2 строки ДО совпадения")
utils.Command("grep -C 2 'pattern' file", "2 строки до и после")
utils.Command("grep -E 'pat1|pat2' file", "расширенные регулярки")
utils.Command("grep -P '\\d+' file", "Perl-совместимые regex")
utils.Command("grep -o 'pattern' file", "только совпадающая часть")
utils.Command("grep -w 'word' file", "только целые слова")
fmt.Println()
utils.Println(utils.ColorBold + "sed — потоковый редактор:" + utils.ColorReset)
utils.Code(`# Синтаксис: sed 'команда' файл
# -i изменить файл на месте
# -E расширенные регулярки
# Замена (s substitute):
sed 's/old/new/' file # первое вхождение в каждой строке
sed 's/old/new/g' file # все вхождения (global)
sed 's/old/new/gi' file # без учёта регистра
sed 's/old/new/2' file # второе вхождение
# Разделитель можно менять (удобно для путей):
sed 's|/old/path|/new/path|g' file
sed 's#/etc#/conf#g' file
# Изменить файл на месте:
sed -i 's/old/new/g' file.conf
sed -i.bak 's/old/new/g' file.conf # сохранить бэкап .bak
# Удаление строк:
sed '/pattern/d' file # удалить строки с паттерном
sed '5d' file # удалить 5-ю строку
sed '2,10d' file # удалить строки 2-10
sed '/^$/d' file # удалить пустые строки
sed '/^#/d' file # удалить комментарии
# Вставка и добавление:
sed '3a новая строка' file # добавить после строки 3
sed '3i новая строка' file # вставить перед строкой 3
sed '$a последняя' file # добавить в конец
# Вывод конкретных строк:
sed -n '5,10p' file # напечатать строки 5-10
sed -n '/start/,/end/p' file # между паттернами
# Несколько команд:
sed -e 's/foo/bar/' -e 's/baz/qux/' file
sed 's/foo/bar/; s/baz/qux/' file
# Практические примеры:
# Удалить комментарии и пустые строки:
sed '/^#/d; /^$/d' nginx.conf
# Заменить IP во всех конфигах:
sed -i 's/192\.168\.1\.100/10\.0\.0\.1/g' /etc/nginx/*.conf
# Добавить строку после первого совпадения:
sed '/\[global\]/a log level = 2' /etc/samba/smb.conf`)
utils.Println(utils.ColorBold + "awk — обработка текста по полям:" + utils.ColorReset)
utils.Code(`# awk обрабатывает текст построчно, разбивая на поля.
# По умолчанию разделитель пробел/таб.
# Поля: $1 $2 $3 ... $NF (последнее), $0 (вся строка)
# NF количество полей, NR номер строки
# Вывод конкретного поля:
awk '{print $1}' file # первое поле
awk '{print $1, $3}' file # первое и третье
awk '{print NR, $0}' file # с номерами строк
# Другой разделитель (-F):
awk -F: '{print $1}' /etc/passwd # имена пользователей
awk -F: '{print $1, $6}' /etc/passwd # имя и домашняя директория
awk -F, '{print $2}' data.csv # второй столбец CSV
# Условия:
awk '$3 > 1000' file # строки где 3-е поле > 1000
awk '/pattern/ {print $0}' file # строки с паттерном
awk '$1 == "root"' /etc/passwd # строки где $1 = "root"
# Вычисления:
awk '{sum += $1} END {print sum}' file # сумма первого столбца
awk 'END {print NR}' file # количество строк (= wc -l)
# BEGIN и END блоки:
awk 'BEGIN {print "Начало"} {print $1} END {print "Конец"}' file
# Переменные и форматирование:
awk -F: '{printf "%-20s %s\n", $1, $6}' /etc/passwd
# Практические примеры:
# Топ процессов по CPU:
ps aux | awk 'NR>1 {print $3, $11}' | sort -rn | head -10
# Сумма размеров файлов (ls -l):
ls -l | awk '{sum += $5} END {print sum " bytes"}'
# Уникальные IP из лога nginx:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# Обработка CSV:
awk -F, 'NR>1 && $3 > 100 {print $1, $2}' report.csv`)
utils.Footer()
}

View file

@ -0,0 +1,223 @@
package linuxmodules
import (
"fmt"
"rubric/utils"
)
var UsersModule = Module{
Key: "users",
Aliases: []string{"u", "perms", "sudo", "права"},
Title: "Пользователи, права и sudo",
Description: "Темы 1720: su, sudo, пользователи, группы, права на файлы",
Run: showUsers,
}
func showUsers() {
utils.Header("Linux — Пользователи, права и sudo")
// ─── 19. Пользователи и группы ───────────────────────────────
utils.Section("19. Пользователи и группы")
utils.Println("В Linux каждый файл принадлежит пользователю и группе.")
utils.Println("Каждый процесс запускается от имени определённого пользователя.")
fmt.Println()
utils.Println(utils.ColorBold + "Основные файлы пользователей:" + utils.ColorReset)
utils.Code(`/etc/passwd список пользователей
/etc/shadow хэши паролей (только root)
/etc/group группы
# Формат /etc/passwd:
# имя:пароль:UID:GID:комментарий:home:shell
alice:x:1000:1000:Alice Smith:/home/alice:/bin/bash
root:x:0:0:root:/root:/bin/bash
# x пароль в /etc/shadow
# UID 0 root (суперпользователь)
# UID 1-999 системные пользователи
# UID 1000+ обычные пользователи
# Формат /etc/group:
# имя:пароль:GID:члены
sudo:x:27:alice,bob
docker:x:999:alice`)
utils.Println(utils.ColorBold + "Информация о пользователях:" + utils.ColorReset)
utils.Command("id", "UID, GID и группы текущего пользователя")
utils.Command("id alice", "информация о пользователе alice")
utils.Command("whoami", "имя текущего пользователя")
utils.Command("groups", "группы текущего пользователя")
utils.Command("getent passwd alice", "запись alice из /etc/passwd")
utils.Command("getent group docker", "участники группы docker")
fmt.Println()
utils.Println(utils.ColorBold + "Управление пользователями (root):" + utils.ColorReset)
utils.Command("useradd alice", "создать пользователя")
utils.Command("useradd -m -s /bin/bash -G sudo alice", "с домашней директорией, оболочкой и группой")
utils.Command("passwd alice", "установить пароль")
utils.Command("usermod -aG docker alice", "добавить alice в группу docker")
utils.Command("usermod -s /bin/zsh alice", "изменить оболочку")
utils.Command("usermod -L alice", "заблокировать учётную запись")
utils.Command("usermod -U alice", "разблокировать")
utils.Command("userdel alice", "удалить пользователя")
utils.Command("userdel -r alice", "удалить с домашней директорией")
fmt.Println()
utils.Println(utils.ColorBold + "Управление группами:" + utils.ColorReset)
utils.Command("groupadd developers", "создать группу")
utils.Command("groupdel developers", "удалить группу")
utils.Command("gpasswd -a alice developers", "добавить alice в группу")
utils.Command("gpasswd -d alice developers", "удалить alice из группы")
fmt.Println()
utils.Note("После добавления в группу пользователь должен перелогиниться. Или: newgrp groupname")
// ─── 20. Права на файлы ───────────────────────────────────────
utils.Section("20. Права на файлы")
utils.Println(utils.ColorBold + "Структура прав доступа:" + utils.ColorReset)
utils.Code(`ls -l file.txt
-rw-r--r-- 1 alice users 1024 Jan 15 10:00 file.txt
9 бит прав
тип файла (- файл, d директория, l ссылка...)
Права разделены на 3 группы по 3 бита:
rwx rwx rwx
other (остальные пользователи)
group (группа владельца)
owner (владелец)
r read (чтение): 4
w write (запись): 2
x execute (выполнение): 1
- нет права: 0
Пример: rw-r--r--
owner: rw- = 6 (4+2) чтение и запись
group: r-- = 4 только чтение
other: r-- = 4 только чтение
Численно: 644`)
utils.Println(utils.ColorBold + "chmod — изменить права:" + utils.ColorReset)
utils.Code(`# Числовой (восьмеричный) способ:
chmod 644 file.txt # rw-r--r--
chmod 755 script.sh # rwxr-xr-x
chmod 600 private.key # rw-------
chmod 777 dir/ # rwxrwxrwx (небезопасно!)
chmod 750 script.sh # rwxr-x---
# Символьный способ:
chmod u+x script.sh # добавить execute владельцу
chmod g-w file.txt # убрать write у группы
chmod o-r secret.txt # убрать чтение у остальных
chmod a+r public.txt # добавить чтение всем (a = all)
chmod u+x,g-w file # несколько изменений
chmod go=r file.txt # установить группе и остальным только r
# Рекурсивно:
chmod -R 755 /var/www/html/`)
utils.Println(utils.ColorBold + "Типичные значения прав:" + utils.ColorReset)
utils.Code(`644 rw-r--r-- обычный файл (конфиги, тексты)
755 rwxr-xr-x исполняемый файл, директория
700 rwx------ личный скрипт/директория
600 rw------- приватный ключ, .env файл
640 rw-r----- конфиг с секретами (owner + group)
664 rw-rw-r-- файл для работы в группе
1777 rwxrwxrwt /tmp (sticky bit)`)
utils.Println(utils.ColorBold + "chown — изменить владельца:" + utils.ColorReset)
utils.Command("chown alice file.txt", "изменить владельца")
utils.Command("chown alice:users file.txt", "изменить владельца и группу")
utils.Command("chown :users file.txt", "изменить только группу")
utils.Command("chown -R alice:alice /home/alice/", "рекурсивно")
utils.Command("chgrp users file.txt", "изменить только группу")
fmt.Println()
utils.Println(utils.ColorBold + "Специальные биты:" + utils.ColorReset)
utils.Code(`SUID (Set User ID) 4000:
Файл запускается с правами владельца файла, а не запускающего.
chmod u+s /usr/bin/passwd # или chmod 4755
ls -la: -rwsr-xr-x (s вместо x у владельца)
Пример: passwd изменяет /etc/shadow (root-файл)
SGID (Set Group ID) 2000:
Файл: запускается от имени группы файла.
Директория: новые файлы наследуют группу директории.
chmod g+s /shared/ # или chmod 2755
ls -la: drwxrwsr-x
Sticky Bit 1000:
Директория: файл может удалить только его владелец.
chmod +t /tmp/ # или chmod 1777
ls -la: drwxrwxrwt
Применение: /tmp, /var/tmp`)
utils.Println(utils.ColorBold + "umask — маска прав по умолчанию:" + utils.ColorReset)
utils.Code(`umask определяет права, которые НЕ назначаются новым файлам.
umask # показать текущую маску (обычно 0022)
umask 0022 # установить маску
# Как работает:
# Файлы создаются с 666, директории с 777.
# Umask 022 вычитается:
# 666 - 022 = 644 (файлы: rw-r--r--)
# 777 - 022 = 755 (директории: rwxr-xr-x)
# Umask 077:
# 666 - 077 = 600 (файлы: rw-------)
# 777 - 077 = 700 (директории: rwx------)
# Установить постоянно в ~/.bashrc:
umask 0027`)
// ─── 1718. su и sudo ─────────────────────────────────────────
utils.Section("1718. su, sudo и visudo")
utils.Println(utils.ColorBold + "su — Switch User:" + utils.ColorReset)
utils.Command("su -", "переключиться в root (login shell, нужен пароль root)")
utils.Command("su", "переключиться в root (без login shell)")
utils.Command("su - alice", "переключиться в alice")
utils.Command("su -c 'команда' alice", "выполнить команду от имени alice")
fmt.Println()
utils.Code(`Разница su vs su -:
su только смена UID, переменные окружения остаются
su - полноценный вход, загружается окружение пользователя
(PATH, HOME и т.д.)
Выйти из su: exit или Ctrl+D`)
utils.Println(utils.ColorBold + "sudo — выполнить как другой пользователь:" + utils.ColorReset)
utils.Command("sudo command", "выполнить команду как root")
utils.Command("sudo -u alice command", "выполнить от имени alice")
utils.Command("sudo -i", "интерактивная сессия root (= su -)")
utils.Command("sudo -s", "оболочка root с текущим окружением")
utils.Command("sudo -l", "показать разрешённые команды для текущего пользователя")
utils.Command("sudo -l -U alice", "разрешённые команды для alice")
utils.Command("sudo !!", "повторить последнюю команду с sudo")
fmt.Println()
utils.Code(`sudo кэширует аутентификацию на 15 минут (по умолчанию).
sudo -k сбросить кэш (следующая команда потребует пароль)`)
utils.Println(utils.ColorBold + "visudo — редактирование /etc/sudoers:" + utils.ColorReset)
utils.Code(`# НИКОГДА не редактируйте /etc/sudoers напрямую!
# visudo проверяет синтаксис перед сохранением.
sudo visudo
# Формат правил:
# WHO WHERE=(AS_WHOM) WHAT
# Примеры /etc/sudoers:
root ALL=(ALL:ALL) ALL # root имеет все права
%sudo ALL=(ALL:ALL) ALL # группа sudo все права
%wheel ALL=(ALL:ALL) ALL # RHEL: группа wheel
alice ALL=(ALL) ALL # alice все команды
alice ALL=(ALL) NOPASSWD:ALL # без пароля (небезопасно!)
bob ALL=(root) /usr/bin/apt # только apt от root
netadmin ALL=(root) /usr/bin/nmtui # только nmtui
helpdesk ALL=(root) /usr/bin/passwd, !/usr/bin/passwd root # пароли кроме root
# Файлы из /etc/sudoers.d/ включаются автоматически.
# Лучше создавать файл там, а не редактировать sudoers:
sudo visudo -f /etc/sudoers.d/alice`)
utils.Footer()
}

BIN
rubric

Binary file not shown.