Отобразить список открытых файлов и псевдофайлов, в том числе и сокетов, как локальных, так и протоколов TCP и UDP, можно с помощью команды
К примеру, показать все TCP и UDP сокеты
Показать все TCP и UDP сокеты, связанные с адресом
Тоже самое, но при отображении не преобразовывать адреса хостов и номера портов в доменные имена и названия сервисов.
Показать все TCP сокеты; при отображении не преобразовывать адреса хостов и номера портов.
Показать все UDP сокеты, связанные с адресом
lsof К примеру, показать все TCP и UDP сокеты
lsof -i Показать все TCP и UDP сокеты, связанные с адресом
192.168.1.5. lsof -i@192.168.1.5 Тоже самое, но при отображении не преобразовывать адреса хостов и номера портов в доменные имена и названия сервисов.
lsof -i@192.168.1.5 -n -P Показать все TCP сокеты; при отображении не преобразовывать адреса хостов и номера портов.
lsof -i TCP -n -P Показать все UDP сокеты, связанные с адресом
192.168.1.5; при отображении не преобразовывать адреса хостов и номера портов. lsof -i UDP@192.168.1.5 -n -PСистемному администратору или DevOps-инженеру часто требуется быстро собрать информацию о сервере: версия ОС, ресурсы, нагрузка, сеть, установленные пакеты и т.д.
Обычно это делается набором команд вроде
Но что если всё это можно объединить в один универсальный отчёт, создаваемый по расписанию и сохраняемый в файл?
Для этого идеально подойдёт небольшой Bash-скрипт, который собирает ключевые метрики и формирует системный отчёт.
Для запуска:
Создаётся файл вроде:
Обычно это делается набором команд вроде
lscpu, free -h, df -h, ip a, uptime и многих других.Но что если всё это можно объединить в один универсальный отчёт, создаваемый по расписанию и сохраняемый в файл?
Для этого идеально подойдёт небольшой Bash-скрипт, который собирает ключевые метрики и формирует системный отчёт.
#!/bin/bash
# sysreport.sh — генерация системного отчёта для Linux
REPORT="$HOME/sysreport_$(hostname)_$(date +%F_%H-%M).txt"
{
echo "======================================"
echo "🖥 СИСТЕМНЫЙ ОТЧЁТ ($(hostname))"
echo "======================================"
echo "Дата: $(date)"
echo "Пользователь: $USER"
echo "--------------------------------------"
echo ""
echo "=== ОС и ядро ==="
lsb_release -a 2>/dev/null || cat /etc/os-release
uname -a
echo ""
echo "=== Аппаратные данные ==="
echo "CPU:"
lscpu | grep -E 'Model name|CPU\(s\)|Thread|Core'
echo ""
echo "Память:"
free -h
echo ""
echo "Диски:"
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT
echo ""
echo "Файловые системы:"
df -hT | grep -v tmpfs
echo ""
echo "=== Сеть ==="
ip -brief address
echo ""
echo "Маршруты:"
ip route show
echo ""
echo "DNS-серверы:"
grep "nameserver" /etc/resolv.conf
echo ""
echo "=== Нагрузка и процессы ==="
echo "Uptime: $(uptime -p)"
echo "Средняя загрузка: $(uptime | awk -F'load average:' '{print $2}')"
echo "Топ-5 по CPU:"
ps -eo pid,comm,%cpu --sort=-%cpu | head -6
echo ""
echo "Топ-5 по памяти:"
ps -eo pid,comm,%mem --sort=-%mem | head -6
echo ""
echo "=== Активные подключения ==="
sudo netstat -tulnp 2>/dev/null | head -10 || ss -tulnp | head -10
echo ""
echo "=== Последние входы пользователей ==="
last -n 5
echo ""
echo "=== Обновления системы ==="
if command -v apt &>/dev/null; then
apt list --upgradable 2>/dev/null | grep -v "Listing" || echo "Все пакеты обновлены."
elif command -v dnf &>/dev/null; then
dnf check-update || echo "Все пакеты обновлены."
fi
} > "$REPORT"
echo "✅ Отчёт сохранён в: $REPORT"
Для запуска:
chmod +x sysreport.sh
./sysreport.shСоздаётся файл вроде:
/home/admin/sysreport_server01_2025-11-12_14-05.txtВстроенная команда
Команда
Она ничего не делает, ничего не выводит и всегда возвращает
Примеры:
• Проверка обязательных переменных
Если переменной нет — Bash мгновенно завершит скрипт с ошибкой.
• «Пустое» вычисление
Строка выглядит как no-op, но выполняет арифметику.
• Бесконечный цикл
Лучше, чем
: — «делай ничего, но успешно»Команда
: есть в POSIX, но почти никто не использует её в реальных скриптах.Она ничего не делает, ничего не выводит и всегда возвращает
0.Примеры:
• Проверка обязательных переменных
: "${DB_HOST:?Переменная DB_HOST обязательна}"Если переменной нет — Bash мгновенно завершит скрипт с ошибкой.
• «Пустое» вычисление
i=0
: $((i++))
echo "$i" # 1Строка выглядит как no-op, но выполняет арифметику.
• Бесконечный цикл
while :; do
echo "Работаю..."
sleep 1
doneЛучше, чем
while true, потому что не вызывает внешнюю команду$PIPESTATUS — статусы всех команд в pipelineОбычное поведение Bash:
cmd1 | cmd2 | cmd3
echo $? # ← статус *последней* командыНо если
cmd1 сломалась — вы не узнаете.Пример:
grep ERROR log.txt | sort | uniq
echo "${PIPESTATUS[@]}"Выход, например:
1 0 0Практическая польза:
Проверка pipeline, который не должен молча ломаться:
grep "$pattern" logfile |
awk '{print $2}' |
sort -u
if (( PIPESTATUS[0] != 0 )); then
echo "Ошибка: grep ничего не нашёл"
fiМагические модификаторы строк
Пример:
Практическое применение:
${var@Q}, ${var@U}, ${var@L}Пример:
v="Hello World"
echo "${v@Q}" # 'Hello World'
echo "${v@U}" # HELLO WORLD
echo "${v@L}" # hello worldПрактическое применение:
${var@Q} — идеально подходит для безопасной сериализации аргументов в логи:echo "Запускаю с аргументом: ${user_input@Q}"Файловые дескрипторы в Bash
Когда мы пишем Bash-скрипты, большинство операций с файлами выглядит максимально просто:
Но за этими короткими операторами скрывается мощная система: файловые дескрипторы (FD).
А знание о них открывает возможности, которые обычное перенаправление не покрывает в принципе: работа с несколькими файлами, сложные пайплайны, межпроцессное взаимодействие и даже работа с потоками как с объектами.
• Что такое файловые дескрипторы?
У каждого процесса в Linux есть три стандартных канала:
FD Назначение
Но процесс может иметь дополнительные дескрипторы:
Это такие же каналы ввода-вывода, как и 0–2, только вы сами решаете, куда они ведут.
• Зачем нужны дополнительные FD?
Обычное перенаправление
То есть вы не можете «последовательно читать два файла» в одном цикле:
Более того, невозможно одновременно читать из одного файла и писать в другой ― в рамках одного while read.
Файловые дескрипторы это исправляют.
• Открываем файл на чтение в FD 3
Теперь файл открыт и доступен по номеру FD 3.
Читаем:
Закрываем:
• Открываем файл на запись в FD 4
• Пример: одновременно читать один файл и писать в другой
• Пример: два входных файла одновременно
• Подводный камень: FD могут конфликтовать
Большая проблема классического подхода:
- вы вручную выбираете номер,
- FD может быть занят библиотекой или другим скриптом,
- при вложенных bash-функциях конфликт становится реальным.
Например, если вы выбрали FD 3, а ваш скрипт был вызван другой программой, которая тоже использует FD 3 ― поведение будет непредсказуемым.
Решение существует, и оно элегантно.
Оно появилось в современных версиях Bash, но о нём почти никто не знает.
Это — динамические файловые дескрипторы через
Когда мы пишем Bash-скрипты, большинство операций с файлами выглядит максимально просто:
cmd < input.txt
cmd > output.txt
cmd >> output.txtНо за этими короткими операторами скрывается мощная система: файловые дескрипторы (FD).
А знание о них открывает возможности, которые обычное перенаправление не покрывает в принципе: работа с несколькими файлами, сложные пайплайны, межпроцессное взаимодействие и даже работа с потоками как с объектами.
• Что такое файловые дескрипторы?
У каждого процесса в Linux есть три стандартных канала:
FD Назначение
0 stdin (ввод)1 stdout (вывод)2 stderr (ошибки)Но процесс может иметь дополнительные дескрипторы:
3, 4, 5 … — хоть до сотен.Это такие же каналы ввода-вывода, как и 0–2, только вы сами решаете, куда они ведут.
• Зачем нужны дополнительные FD?
Обычное перенаправление
< file может быть применено только один раз.То есть вы не можете «последовательно читать два файла» в одном цикле:
while read line; do …; done < file1 < file2 # так не работаетБолее того, невозможно одновременно читать из одного файла и писать в другой ― в рамках одного while read.
Файловые дескрипторы это исправляют.
• Открываем файл на чтение в FD 3
exec 3< file.txtТеперь файл открыт и доступен по номеру FD 3.
Читаем:
read line <&3
echo "$line"Закрываем:
exec 3<&-• Открываем файл на запись в FD 4
exec 4> output.log
echo "Hello" >&4
exec 4>&-• Пример: одновременно читать один файл и писать в другой
exec3< input.txt
exec 4> output.txt
while read -r line <&3; do
echo "[LOG] $line" >&4
done
exec 3<&-
exec 4>&-• Пример: два входных файла одновременно
exec 3< fileA.txt
exec 4< fileB.txt
read A <&3
read B <&4
echo "A: $A"
echo "B: $B"
exec 3<&-
exec 4<&-• Подводный камень: FD могут конфликтовать
Большая проблема классического подхода:
- вы вручную выбираете номер,
- FD может быть занят библиотекой или другим скриптом,
- при вложенных bash-функциях конфликт становится реальным.
Например, если вы выбрали FD 3, а ваш скрипт был вызван другой программой, которая тоже использует FD 3 ― поведение будет непредсказуемым.
Решение существует, и оно элегантно.
Оно появилось в современных версиях Bash, но о нём почти никто не знает.
Это — динамические файловые дескрипторы через
{fd}.Динамические файловые дескрипторы в Bash: скрытая фича, которая всё меняет
Bash давно умеет сам выбирать безопасные свободные FD, и делает это удивительно удобно.
Этот пост — о малоизвестном синтаксисе
• Что такое динамические файловые дескрипторы?
Синтаксис:
Смысл:
- Bash находит свободный номер FD, например
- Открывает файл
- Записывает номер (
Проверка:
Теперь файл привязан к
• Почему это важно?
- не нужно угадывать свободный номер
- нет конфликтов с библиотеками
- можно открывать десятки файлов подряд
- можно работать с каналами процессов и
- проще читать и писать разные потоки одновременно
• Простейший пример:
FD создаётся динамически, закрывается безопасно.
• Два файла одновременно (без конфликтов)
Не нужно думать про FD 3, 4, 5…
• Чтение + запись одновременно
• Работа с потоками процессов:
Динамические FD работают не только с файлами:
• Реальный практический пример:
Задача:
— читать лог,
— писать его полностью в один файл,
— строки с ERROR писать отдельно,
— считать WARNING.
Решение:
С классическими FD 3, 4, 5 такой код был бы более рискованным — конфликты гарантированы.
• Как увидеть, что FD создан?
После:
увидите:
Bash давно умеет сам выбирать безопасные свободные FD, и делает это удивительно удобно.
Этот пост — о малоизвестном синтаксисе
{fd} и реальных кейсах его применения.• Что такое динамические файловые дескрипторы?
Синтаксис:
exec {fd}< file.txtСмысл:
- Bash находит свободный номер FD, например
11.- Открывает файл
file.txt для чтения.- Записывает номер (
11) в переменную fd.Проверка:
echo "$fd" # например 11Теперь файл привязан к
FD 11, и вы работаете с переменной $fd.• Почему это важно?
- не нужно угадывать свободный номер
FD- нет конфликтов с библиотеками
- можно открывать десятки файлов подряд
- можно работать с каналами процессов и
/dev/fd/*- проще читать и писать разные потоки одновременно
• Простейший пример:
exec {fd}< file.txt
while read -r line <&$fd; do
echo "$line"
done
exec {fd}<&-FD создаётся динамически, закрывается безопасно.
• Два файла одновременно (без конфликтов)
exec {a}< fileA.txt
exec {b}< fileB.txt
read A <&$a
read B <&$b
echo "A: $A"
echo "B: $B"
exec {a}<&-
exec {b}<&-Не нужно думать про FD 3, 4, 5…
• Чтение + запись одновременно
exec {in}< data.txt
exec {out}> log.txt
while read -r line <&$in; do
echo "line: $line" >&$out
done
exec {in}<&-
exec {out}>&-• Работа с потоками процессов:
<( … )Динамические FD работают не только с файлами:
exec {tmpfd}<(sed 's/foo/bar/g' data.txt)
cat <&$tmpfd
exec {tmpfd}<&-<(...) создаёт временный поток (/dev/fd/…), а {tmpfd} превращает его в аккуратный FD.• Реальный практический пример:
Задача:
— читать лог,
— писать его полностью в один файл,
— строки с ERROR писать отдельно,
— считать WARNING.
Решение:
exec {in}< log.txt
exec {all}> all.log
exec {err}> errors.log
warnings=0
while read -r line <&$in; do
echo "$line" >&$all
if [[ $line == *ERROR* ]]; then
echo "$line" >&$err
fi
[[ $line == *WARNING* ]] && ((warnings++))
done
exec {in}<&-
exec {all}>&-
exec {err}>&-
echo "Warnings: $warnings"С классическими FD 3, 4, 5 такой код был бы более рискованным — конфликты гарантированы.
• Как увидеть, что FD создан?
ls -l /proc/$$/fdПосле:
exec {fd}< fileувидите:
11 -> fileИнструмент сетевой диагностики MTR
MTR (My Traceroute) — инструмент для сетевой диагностики в Linux. Он сочетает функциональность
MTR работает в интерактивном режиме и может генерировать отчеты. Он часто используется сетевыми администраторами, разработчиками и пользователями для диагностики интернет-соединений.
Установка MTR
MTR обычно предустановлен в большинстве дистрибутивов Linux, но если нет, установите его через менеджер пакетов:
Ubuntu/Debian:
После установки проверьте версию:
Основные команды и опции
Запуск MTR прост:
Ключевые опции:
В интерактивном режиме (без
Примеры использования
• Базовый интерактивный запуск:
Это откроет интерактивное окно с таблицей: столбцы показывают хоп (узел), потерю пакетов, среднюю задержку, лучший/худший/последний пинг и jitter (колебания).
• Генерация отчета:
Выводит текстовый отчет, который можно сохранить:
• Тестирование с TCP (для обхода ICMP-блокировок):
Полезно, если ICMP заблокирован фаерволами.
• Мониторинг с интервалом 0.5 секунды:
• Проверка локальной сети:
(Замените IP на ваш роутер или сервер.)
Интерпретация результатов
Loss %: Процент потерянных пакетов. Высокий (более 5%) указывает на проблемы.
Snt: Отправлено пакетов.
Last: Последняя задержка.
Avg: Средняя задержка.
Best/Wrst: Лучшая/худшая задержка.
StDev: Стандартное отклонение (jitter) — показывает стабильность.
MTR (My Traceroute) — инструмент для сетевой диагностики в Linux. Он сочетает функциональность
traceroute и ping, предоставляя реал-тайм мониторинг пути пакетов от вашего компьютера до целевого хоста. MTR работает в интерактивном режиме и может генерировать отчеты. Он часто используется сетевыми администраторами, разработчиками и пользователями для диагностики интернет-соединений.
Установка MTR
MTR обычно предустановлен в большинстве дистрибутивов Linux, но если нет, установите его через менеджер пакетов:
Ubuntu/Debian:
sudo apt update && sudo apt install mtrПосле установки проверьте версию:
mtr --version.Основные команды и опции
Запуск MTR прост:
mtr [опции] <цель>, где <цель> — IP-адрес или домен (например, google.com).Ключевые опции:
-r (report mode): Генерирует статический отчет вместо интерактивного режима. Полезно для скриптов или логов.-c <число>: Количество пакетов для отправки (по умолчанию 10 в report mode).-i <секунды>: Интервал между пакетами (по умолчанию 1 секунда).-n: Не разрешать имена хостов (показывать только IP).-w: Широкий вывод (больше столбцов).-p: Режим ping (только ping без traceroute).-T: Использовать TCP вместо ICMP (полезно для обхода фаерволов).-U: Использовать UDP вместо ICMP.--no-dns: Отключить разрешение DNS.-h: Справка по всем опциям.В интерактивном режиме (без
-r) MTR показывает динамическую таблицу. Используйте клавиши:q — выход.d — переключить режим отображения (статистика/график).j — перейти к следующему узлу.k — перейти к предыдущему узлу.? — справка по клавишам.Примеры использования
• Базовый интерактивный запуск:
mtr google.comЭто откроет интерактивное окно с таблицей: столбцы показывают хоп (узел), потерю пакетов, среднюю задержку, лучший/худший/последний пинг и jitter (колебания).
• Генерация отчета:
mtr -r -c 10 google.comВыводит текстовый отчет, который можно сохранить:
mtr -r -c 10 google.com > report.txt.• Тестирование с TCP (для обхода ICMP-блокировок):
mtr -T google.comПолезно, если ICMP заблокирован фаерволами.
• Мониторинг с интервалом 0.5 секунды:
mtr -i 0.5 -c 20 example.com• Проверка локальной сети:
mtr 192.168.1.1(Замените IP на ваш роутер или сервер.)
Интерпретация результатов
Loss %: Процент потерянных пакетов. Высокий (более 5%) указывает на проблемы.
Snt: Отправлено пакетов.
Last: Последняя задержка.
Avg: Средняя задержка.
Best/Wrst: Лучшая/худшая задержка.
StDev: Стандартное отклонение (jitter) — показывает стабильность.
Предположим, что вам нужно запустить приложение с графическим интерфейсом 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 и т.д.)Примеры запуска:
Интерактивно (пишем в терминале)
$ ./script.sh
Добро пожаловать! Скрипт запущен интерактивно.
Можно показывать красивые подсказки, приглашения, меню…
Основная работа скрипта продолжается...
Неинтерактивно (через pipe)
$ echo | bash script.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