Предположим, что вам нужно запустить приложение с графическим интерфейсом gedit с помощью соответствующей команды и закрыть окно эмулятора терминала без завершения работы этого приложения.
В этом случае сначала следует запустить его в фоновом режиме:
В результате вы увидите окно приложения, а в окне терминала будет выведен идентификатор соответствующей задачи, например:
Теперь следует удалить задачу с известным идентификатором из таблицы задач командной оболочки:
После этого вы можете закрыть окно эмулятора терминала. Приложение с графическим интерфейсом будет работать как ни в чем ни бывало.
В этом случае сначала следует запустить его в фоновом режиме:
gedit &В результате вы увидите окно приложения, а в окне терминала будет выведен идентификатор соответствующей задачи, например:
[1] 14191Теперь следует удалить задачу с известным идентификатором из таблицы задач командной оболочки:
disown 14191После этого вы можете закрыть окно эмулятора терминала. Приложение с графическим интерфейсом будет работать как ни в чем ни бывало.
globstar и рекурсивный **Включаем:
shopt -s globstarИспользуем:
echo **/*.pyПолный обход директорий — без
find.Пример реального скрипта:
for f in **/*.md; do
pandoc "$f" -o "${f%.md}.html"
doneНесколько распространённых и полезных идиом Bash
1. Проверка существования файла или директории
Используется для проверки файлов (
2. Условное присваивание переменной (с дефолтным значением)
Если переменная
3. Цикл по файлам в директории
Простой способ итерации по файлам. Осторожно с пробелами в именах — используй
4. Чтение строк из файла с циклом while
Безопасное чтение файла построчно, без потери пробелов.
5. Проверка успешности команды
Bash возвращает код выхода (
6. Here-документ для многострочного ввода
Полезно для создания конфигов или скриптов на лету.
7. Trap для очистки при выходе
Автоматическая очистка временных файлов при завершении скрипта. Можно ловить сигналы вроде INT (
8. Set -e для строгого режима
Делает скрипт "строгим" — он прерывается на первой неудачной команде. Комбинируй с
1. Проверка существования файла или директории
if [ -f "$file" ]; then
echo "Файл существует"
fiИспользуется для проверки файлов (
-f), директорий (-d), исполняемых файлов (-x) и т.д. Полезно перед операциями, чтобы избежать ошибок.2. Условное присваивание переменной (с дефолтным значением)
name=${NAME:-"Гость"}Если переменная
NAME пустая или не установлена, присваивает "Гость". Аналогично ${VAR:=value} для установки.3. Цикл по файлам в директории
for file in *.txt; do
echo "Обрабатываю $file"
doneПростой способ итерации по файлам. Осторожно с пробелами в именах — используй
for file in *; do и кавычки.4. Чтение строк из файла с циклом while
while IFS= read -r line; do
echo "Строка: $line"
done < input.txtБезопасное чтение файла построчно, без потери пробелов.
IFS= отключает разделение, -r сохраняет бэкслеши.5. Проверка успешности команды
if command; then
echo "Команда прошла успешно"
else
echo "Ошибка"
fiBash возвращает код выхода (
0 — успех). Это основа для обработки ошибок.6. Here-документ для многострочного ввода
cat << EOF
Это многострочный текст.
EOFПолезно для создания конфигов или скриптов на лету.
<< — heredoc, EOF — маркер конца.7. Trap для очистки при выходе
trap 'rm -f /tmp/tempfile' EXITАвтоматическая очистка временных файлов при завершении скрипта. Можно ловить сигналы вроде INT (
Ctrl+C).8. Set -e для строгого режима
set -e
# Теперь скрипт выходит при первой ошибкеДелает скрипт "строгим" — он прерывается на первой неудачной команде. Комбинируй с
set -u (ошибка на неустановленных переменных) и set -o pipefail (для пайпов).Встроенные команды календарей
Создайте файл
cal: Простой календарь на текущий месяц. cal покажет календарь, cal 2025 — на год, cal -3 — на три месяца. (ncal для альтернативного вида).calendar: Утилита из пакета bsdmainutils (sudo apt install bsdmainutils для Ubuntu). Создайте файл
~/.calendar с событиями в формате "MM/DD/YYYY описание". Команда calendar покажет предстоящие события.at и cron: Для напоминаний. at — одноразовые: echo "notify-send 'Время встречи'" | at 14:00 tomorrow. cron — повторяющиеся: crontab -e и добавьте 0 9 * * 1-5 notify-send "Еженедельный отчет". (Установите at через пакетный менеджер, если нужно).Проверка, выполняется ли скрипт в interactive shell
В переменной
Cпецпеременная Bash (
Например:
Примеры запуска:
Интерактивно (пишем в терминале)
Неинтерактивно (через pipe)
Через cron (эффект аналогичный)
[[ $- == *i* ]]В переменной
$- содержатся флаги текущего shell, и если там есть буква i, то оболочка интерактивная.Допустим, у нас есть скрипт, который выводит приветствие только если его запустили интерактивно (например, вручную), но молчит, когда его запускает cron, systemd, ssh-скрипты и т.п.
#!/usr/bin/env bash
# Идиома: определение интерактивности оболочки
if [[ $- == *i* ]]; then
echo "Добро пожаловать! Скрипт запущен интерактивно."
echo "Можно показывать красивые подсказки, приглашения, меню…"
else
# Ничего не выводим или выводим очень лаконично
echo "non-interactive mode"
fi
echo "Основная работа скрипта продолжается..."
Cпецпеременная Bash (
$-) — список текущих shell-опций.Например:
himBH Где: i → interactive (если есть — оболочка интерактивная). Остальные буквы — разные режимы (h, m, B и т.д.)Примеры запуска:
Интерактивно (пишем в терминале)
$ ./noscript.sh
Добро пожаловать! Скрипт запущен интерактивно.
Можно показывать красивые подсказки, приглашения, меню…
Основная работа скрипта продолжается...
Неинтерактивно (через pipe)
$ echo | bash noscript.sh
non-interactive mode
Основная работа скрипта продолжается...
Через cron (эффект аналогичный)
non-interactive mode
Основная работа скрипта продолжается...
Старший и младший номера устройств
Как мы помним, в UNIX — все есть файл, поэтому каждому устройству в системе соответствует имя этого устройства в каталоге
Каждое именованное устройство в Linux однозначно характеризуется двумя (байтовыми:
Если вы введёте команду
Как мы помним, в UNIX — все есть файл, поэтому каждому устройству в системе соответствует имя этого устройства в каталоге
/dev. Каждое именованное устройство в Linux однозначно характеризуется двумя (байтовыми:
0...255) номерами: старшим номером (major) — номером отвечающим за отдельный класс устройств, и младшим номером (minor) — номером конкретного устройства внутри своего класса. Если вы введёте команду
ls -l, то увидите два числа (разделённые запятой) в каждой записи файла устройства перед датой последней модификации файла, где обычно показывается длина. Эти цифры являются старшим и младшим номером устройства для каждого из них (старшие номера: 1, 4, 7 и 10, а младшие: 1, 3, 5, 64, 65 и 129).Удаление дубликатов файлов по хэшу
#!/bin/bash
# -------------------------------------------
# Скрипт проходит по всем файлам в указанной
# директории, вычисляет их хэши и удаляет
# дубликаты (спрашивая подтверждение).
# -------------------------------------------
# Директория для сканирования.
# Если пользователь не передал путь, используется текущая.
dir="${1:-.}"
# Хэш-алгоритм. Можно заменить на:
# md5sum — быстрее, но менее надёжно
# sha1sum — средне
# sha256sum — медленнее, но максимально надёжно
algo="sha256sum"
# Ассоциативный массив "хэш → путь к оригиналу".
# В нём сохраняются хэши всех уже встреченных файлов.
declare -A seen
echo "-------------------------------------------"
echo " Сканирование директории: $dir"
echo " Алгоритм хеширования: $algo"
echo "-------------------------------------------"
echo
# Используем find для обхода ВСЕХ файлов.
# -type f — только обычные файлы.
# -print0 — вывод с нулевым разделителем, чтобы корректно
# обрабатывать имена с пробелами и спецсимволами.
while IFS= read -r -d '' file; do
# Вычисляем хэш файла. Команда вида:
# sha256sum file | awk '{print $1}'
# выводит только сам хэш без имени.
hash=$($algo "$file" | awk '{print $1}')
# Если этот хэш уже есть в массиве,
# значит, файл-дубликат найден.
if [[ ${seen[$hash]} ]]; then
echo "🔁 Найден дубликат:"
echo " Оригинал: ${seen[$hash]}"
echo " Дубликат: $file"
echo
# Запрашиваем подтверждение удаления.
read -p "Удалить дубликат? [y/N]: " answer
# Удаление только если ответ 'y' или 'Y'
if [[ "$answer" =~ ^[Yy]$ ]]; then
rm -v "$file" # -v — verbose, показывает что удалено
else
echo "Пропуск."
fi
echo
else
# Если хэша нет — запоминаем файл как оригинал.
seen[$hash]="$file"
fi
# Этот синтаксис < <(...) позволяет передавать результат find
# прямо в цикл while (без создания временных файлов).
done < <(find "$dir" -type f -print0)
echo "Готово!"
Чтобы при вводе пароля через
Способ 1. Правильный (через visudo)
Открыть sudoers для редактирования:
Добавить строку:
Сохранить и выйти.
Теперь sudo будет показывать звёздочки при вводе пароля.
Способ 2. Только для текущего пользователя
Создать (или отредактировать) файл:
Добавить:
Например:
sudo отображались звёздочки (*****), нужно включить опцию pwfeedback в настройках sudo.Способ 1. Правильный (через visudo)
Открыть sudoers для редактирования:
sudo visudoДобавить строку:
Defaults pwfeedbackСохранить и выйти.
Теперь sudo будет показывать звёздочки при вводе пароля.
Способ 2. Только для текущего пользователя
Создать (или отредактировать) файл:
sudo visudo -f /etc/sudoers.d/pwfeedbackДобавить:
Defaults:<твой_пользователь> pwfeedbackНапример:
Defaults:alice pwfeedbackОпределяем тип файла в Linux
Существует специальная утилита
Синтаксис:
Расширение для программы file безразлично.
С помощью ключа
Существует специальная утилита
file, которая выполняет определение типа файла. она анализирует начало содержимого файла и находит в нем специальные "сигналы", характерные для определенного типа – бинарного файла, текстового, изображения и др.Синтаксис:
file <filename>Расширение для программы file безразлично.
С помощью ключа
-L мы можем узнать тип файла, на который ссылается файл-ссылка.Проверка файла / директории в Bash
В Bash для этого используют file test operators, чаще всего в
• Базовые проверки:
Файл существует:
Обычный файл:
Директория:
Символьная ссылка:
• Права доступа:
Чтение / запись / выполнение
Проверяет права текущего пользователя, не владельца файла.
• Размер и содержимое:
Файл не пустой:
Файл пустой:
Владение:
Временные атрибуты:
Комбинирование условий:
• Безопасные идиомы:
Проверка перед использованием:
Создать директорию, если нет:
• Частые ошибки:
Неэкранированная переменная:
Использование
• Краткая шпаргалка:
В Bash для этого используют file test operators, чаще всего в
[[ ... ]].• Базовые проверки:
Файл существует:
[[ -e path ]]Обычный файл:
[[ -f path ]]Директория:
[[ -d path ]]Символьная ссылка:
[[ -L path ]]• Права доступа:
Чтение / запись / выполнение
[[ -r path ]] # readable
[[ -w path ]] # writable
[[ -x path ]] # executableПроверяет права текущего пользователя, не владельца файла.
• Размер и содержимое:
Файл не пустой:
[[ -s path ]]Файл пустой:
[[ ! -s path ]]Владение:
[[ -O path ]] # владелец — текущий пользователь
[[ -G path ]] # принадлежит группе пользователяВременные атрибуты:
[[ path -nt other ]] # newer than
[[ path -ot other ]] # older thanКомбинирование условий:
if [[ -f file && -r file ]]; then
echo "Readable file"
fi• Безопасные идиомы:
Проверка перед использованием:
[[ -f "$file" ]] || {
echo "File not found: $file" >&2
exit 1
}Создать директорию, если нет:
[[ -d "$dir" ]] || mkdir -p "$dir"• Частые ошибки:
Неэкранированная переменная:
[[ -f $file ]] # плохо
[[ -f "$file" ]] # правильноИспользование
ls:ls file.txt >/dev/null 2>&1 # плохо
[[ -f file.txt ]] # правильно• Краткая шпаргалка:
-e существует-f обычный файл-d директория-L symlink-r чтение-w запись-x выполнение-s не пустВерсии ядра линукс
Запись версии ядра можно представить в виде: A.B.C-D.
A – это версия ядра, изначально планировалось повышать номер только после значительной переработки ядра, но сейчас это делают после достаточного количества правок и нововведений примерно два раза за десятилетие.
B – это ревизия ядра, обновление происходит каждые 2-3 месяца. Некоторые из них получают долгосрочную поддержку (LTS – long term support). Каждая ревизия имеет большой список изменений, которые сначала проверяют тестировщики.
C и D отвечают за небольшие правки в коде ядра. С увеличивается в том случае, если были обновлены драйверы устройств, а D – когда вышел очередной патч безопасности. Эти номера могут меняться практически каждый день.
Узнать версию ядра можно с помощью команды:
Запись версии ядра можно представить в виде: A.B.C-D.
A – это версия ядра, изначально планировалось повышать номер только после значительной переработки ядра, но сейчас это делают после достаточного количества правок и нововведений примерно два раза за десятилетие.
B – это ревизия ядра, обновление происходит каждые 2-3 месяца. Некоторые из них получают долгосрочную поддержку (LTS – long term support). Каждая ревизия имеет большой список изменений, которые сначала проверяют тестировщики.
C и D отвечают за небольшие правки в коде ядра. С увеличивается в том случае, если были обновлены драйверы устройств, а D – когда вышел очередной патч безопасности. Эти номера могут меняться практически каждый день.
Узнать версию ядра можно с помощью команды:
uname -rСкрипт для просмотра внешних сетевых соединений по процессам
Иногда полезно знать, какие программы на вашем компьютере выходят в интернет.
1.
•
•
•
•
•
2. Фильтрация внешних соединений
•
• Исключает все локальные соединения, оставляя только внешние IP.
3. Извлечение PID и имени процесса
•
•
4. Вывод в удобной форме
Иногда полезно знать, какие программы на вашем компьютере выходят в интернет.
#!/usr/bin/env bash
# Вывод заголовка
echo "Активные сетевые соединения (внешние)"
echo
# Получаем список соединений (TCP/UDP) с PID и именами процессов
ss -tunpH | awk '
# Фильтруем только внешние соединения (не localhost)
$5 !~ /(127\.0\.0\.1|::1)/ {
# Извлекаем PID процесса
match($0, /pid=([0-9]+)/, p)
# Извлекаем имя процесса
match($0, /"([^"]+)"/, c)
# Выводим красиво: PID, имя процесса и удалённый адрес
printf "PID: %-6s ПРОГРАММА: %-15s -> %s\n", p[1], c[1], $5
}'
1.
ss -tunpH•
-t — TCP соединения•
-u — UDP соединения•
-n — показывать IP и порты без преобразования в имена•
-p — показать PID и имя процесса•
-H — без заголовка2. Фильтрация внешних соединений
•
$5 !~ /(127\.0\.0\.1|::1)/• Исключает все локальные соединения, оставляя только внешние IP.
3. Извлечение PID и имени процесса
•
match($0, /pid=([0-9]+)/, p) → PID•
match($0, /"([^"]+)"/, c) → имя программы4. Вывод в удобной форме
PID: 1234 ПРОГРАММА: firefox -> 172.217.16.142:443
PID: 982 ПРОГРАММА: ssh -> 18.197.45.22:22Классическая форк-бомба :(){ :|:& };: в современных версиях Ubuntu (начиная примерно с 18.04–20.04 и точно в 22.04/24.04) не крашит систему, как это было в старых дистрибутивах.
Почему она "не работает"
Ubuntu использует
Когда форк-бомба доходит до этого лимита:
• Дальнейшие fork() начинают падать с ошибкой (bash выдаёт кучу "fork: retry: Resource temporarily unavailable").
• Процессор нагружается на короткое время (несколько секунд–минут).
• Затем всё успокаивается: лишние процессы умирают или просто висят, система остаётся отзывчивой.
Дополнительно может сработать OOM Killer (если памяти не хватит), но в большинстве случаев даже до этого не доходит.
Почему она "не работает"
Ubuntu использует
systemd, который автоматически создаёт для каждого пользователя отдельный cgroup (контроллер ресурсов). По умолчанию в systemd установлен лимит на максимальное количество задач (processes + threads) для одного пользователя — обычно около 33% от системного максимума (kernel.threads-max), что даёт примерно 10–15 тысяч процессов (зависит от конфигурации машины).Когда форк-бомба доходит до этого лимита:
• Дальнейшие fork() начинают падать с ошибкой (bash выдаёт кучу "fork: retry: Resource temporarily unavailable").
• Процессор нагружается на короткое время (несколько секунд–минут).
• Затем всё успокаивается: лишние процессы умирают или просто висят, система остаётся отзывчивой.
Дополнительно может сработать OOM Killer (если памяти не хватит), но в большинстве случаев даже до этого не доходит.
Скачали ISO-образ Ubuntu или программу — проверить, что файл не повреждён и не подменён.
Или сразу проверить:
#На сайте обычно дают SHA256 хеш, например:
# 1a2b3c4d...
sha256sum ubuntu-24.04.iso
# Сравнить вывод с тем, что на сайте
Или сразу проверить:
Bashecho "1a2b3c4d... ubuntu-24.04.iso" | sha256sum --check
# Выведет OK или FAILED
Автоматическая смена обоев из папки
Каждый час ставить новый фон рабочего стола из папки с картинками.
Cкрипт
В cron:
Каждый час ставить новый фон рабочего стола из папки с картинками.
Cкрипт
change_wallpaper.sh — для GNOME:Bash#!/bin/bash
wallpapers=~/pictures/wallpapers/*
random_wall=$(shuf -n1 -e $wallpapers)
gsettings set org.gnome.desktop.background picture-uri "file://$random_wall"
gsettings set org.gnome.desktop.background picture-uri-dark "file://$random_wall"
В cron:
cron0 * * * * /path/change_wallpaper.shАвтоматически выключаем компьютер в определённое время
Выключать ПК каждый день в 23:00 (например, для детского ПК).
Простое решение (в cron):
Или с предупреждением за 10 минут:
Выключать ПК каждый день в 23:00 (например, для детского ПК).
Простое решение (в cron):
cron0 23 * * * shutdown -h nowИли с предупреждением за 10 минут:
cron50 22 * * * wall "Компьютер выключится через 10 минут!"
0 23 * * * shutdown -h now«Xargs: как обрабатывать вывод команд пачками (параллельно!)»
Pipe в Bash крут, но xargs делает его мощнее: берёт ввод и передаёт аргументами другой команде.
Полезно для больших списков (файлы, PID).
Пример: убить процессы по grep
Пояснение:
Практика: с find —
Pipe в Bash крут, но xargs делает его мощнее: берёт ввод и передаёт аргументами другой команде.
Полезно для больших списков (файлы, PID).
-P для параллели.Пример: убить процессы по grep
ps aux | grep "myapp" | awk '{print $2}' | xargs -P 4 killПояснение:
grep находит, awk берёт PID ($2), xargs kill'ит параллельно 4 штуки (-P4).Практика: с find —
find . -name "*.tmp" | xargs rm (без -exec). Экономит время на серверах.Бывает, сервер или рабочая машина начинает «думать» дольше обычного: команды висят, интерфейс лагает, SSH отвечает с задержкой. Не паникуем — 90% случаев решаются системной диагностикой.
Полный чек-лист, когда что-то тормозит:
Шаг 1: Общая картина — что жрёт ресурсы прямо сейчас
Сразу запускаем
Что смотреть:
• CPU: если все ядра на 100% — ищем процесс вверху списка (сортировка по %CPU — нажми F6 → %CPU).
• RAM/Swap: если Swap активно используется (жёлтая полоска) — нехватка памяти, процесс убивает OOM-killer.
• Load Average (вверху): три числа — 1/5/15 мин. Если на 4-ядерной машине >8-12 — перегрузка.
Альтернатива без htop:
Шаг 2: Память — free и vmstat
Ключевые колонки в vmstat:
• r — процессы в очереди на CPU (если > числа ядер — CPU bottleneck)
• b — процессы в uninterruptible sleep (обычно I/O wait)
• si/so — swap in/out (если не нули — памяти не хватает)
• wa — % CPU в I/O wait (высокий — диски тормозят)
Шаг 3: Диски — iostat и iotop
В iostat смотрим:
• %util близко к 100% — диск загружен полностью
• await > 20-30 ms — медленный отклик (SSD должно быть <1 ms)
• svctm устарело, но если высокое — проблемы
Если NVMe/SSD, а util 100% — часто виноваты большие логи или бэкапы.
Шаг 4: CPU детально — mpstat и pidstat
Поможет понять: один поток жрёт одно ядро или нагрузка равномерная.
Шаг 5: Исторические данные — sar (sysstat)
Если проблема не постоянная:
Sysstat по умолчанию собирает данные каждые 10 мин — золотой источник для ночных тормозов.
Шаг 6: Конкретный процесс — strace и perf
Если виновник известен (например, mysqld или java):
Шаг 7: Ядро и аппаратные проблемы
Частые виновники: ошибки диска, перегрев, сетевые драйверы.
Шаг 8: Сеть — если тормозит только удалённо
Полный чек-лист, когда что-то тормозит:
Шаг 1: Общая картина — что жрёт ресурсы прямо сейчас
Сразу запускаем
htop (если нет — sudo apt install htop или dnf install htop).Что смотреть:
• CPU: если все ядра на 100% — ищем процесс вверху списка (сортировка по %CPU — нажми F6 → %CPU).
• RAM/Swap: если Swap активно используется (жёлтая полоска) — нехватка памяти, процесс убивает OOM-killer.
• Load Average (вверху): три числа — 1/5/15 мин. Если на 4-ядерной машине >8-12 — перегрузка.
Альтернатива без htop:
top (Shift+P — сортировка по CPU, Shift+M — по MEM).Шаг 2: Память — free и vmstat
free -h # сколько реально свободно
vmstat -w 1 10 # каждую секунду 10 разКлючевые колонки в vmstat:
• r — процессы в очереди на CPU (если > числа ядер — CPU bottleneck)
• b — процессы в uninterruptible sleep (обычно I/O wait)
• si/so — swap in/out (если не нули — памяти не хватает)
• wa — % CPU в I/O wait (высокий — диски тормозят)
Шаг 3: Диски — iostat и iotop
iostat -xz 1 10 # расширенная стат-а каждую сек.
iotop # как htop, но для I/O (нужен root)В iostat смотрим:
• %util близко к 100% — диск загружен полностью
• await > 20-30 ms — медленный отклик (SSD должно быть <1 ms)
• svctm устарело, но если высокое — проблемы
Если NVMe/SSD, а util 100% — часто виноваты большие логи или бэкапы.
Шаг 4: CPU детально — mpstat и pidstat
mpstat -P ALL 1 10 # нагрузка по каждому ядру
pidstat -u 1 10 # CPU по процессам со временемПоможет понять: один поток жрёт одно ядро или нагрузка равномерная.
Шаг 5: Исторические данные — sar (sysstat)
Если проблема не постоянная:
sar -u 10 5 # CPU сейчас
sar -r # память за день
sar -d # диски за день
sar -n DEV # сетьSysstat по умолчанию собирает данные каждые 10 мин — золотой источник для ночных тормозов.
Шаг 6: Конкретный процесс — strace и perf
Если виновник известен (например, mysqld или java):
strace -p PID -c
# системные вызовы и сколько времени на них
perf top -p PID
# что именно в CPU жрёт (нужен kernel-headers)
perf record -p PID -g sleep 10; perf report
# профилированиеШаг 7: Ядро и аппаратные проблемы
dmesg -T --follow
# последние сообщения ядра с читаемыми датами
cat /proc/interrupts
# если один IRQ очень высокий — драйвер/устройствоЧастые виновники: ошибки диска, перегрев, сетевые драйверы.
Шаг 8: Сеть — если тормозит только удалённо
iftop # кто сколько трафика жрёт
nethogs # по процессам
ping -c 4 google.com
mtr google.com # трассировка + пинг