fa
Feedback
BashTex | Linux

BashTex | Linux

رفتن به کانال در Telegram

Авторский канал для тех, кто хочет глубже погрузиться в мир Linux. Подойдет для разработчиков, системных администраторов и DevOps Реклама: @dad_admin

نمایش بیشتر
2 524
مشترکین
-224 ساعت
-67 روز
اطلاعاتی وجود ندارد30 روز
آرشیو پست ها
Фоновая очередь с приоритетами Когда ты запускаешь десятки фоновых задач - важно не просто кидать их в фон через &, а управлять их приоритетом, нагрузкой и порядком выполнения. 💎 Используем:
nice - задаем приоритет (-20 самый высокий, 19 - самый низкий) wait - ждем завершения задач & - фоновый запуск массив - очередь
🛠 Пример: динамическая очередь с приоритетами

#!/bin/bash

declare -a QUEUE=(
  "sleep 5"   # низкий приоритет
  "sleep 2"   # высокий приоритет
  "sleep 4"
)

declare -a PRIORITY=(
  10   # nice +10 → ниже приоритет
  -5   # nice -5  → выше приоритет
  0
)

for i in "${!QUEUE[@]}"; do
  echo "[*] Запуск: ${QUEUE[$i]} с приоритетом ${PRIORITY[$i]}"
  nice -n "${PRIORITY[$i]}" bash -c "${QUEUE[$i]}" &
done

wait
echo "[+] Все задачи завершены"
Что это даёт?
📍 Задачи с низким приоритетом будут уступать CPU 📍 Высокоприоритетные задачи получат преимущество при выполнении 📍 wait гарантирует, что мы дождёмся всех процессов
▪️ Расширение: Добавь ограничение количества параллельных задач:

MAX_PARALLEL=3
PIDS=()

for i in "${!QUEUE[@]}"; do
  nice -n "${PRIORITY[$i]}" bash -c "${QUEUE[$i]}" &
  PIDS+=($!)

  if (( ${#PIDS[@]} >= MAX_PARALLEL )); then
    wait -n  # ждём завершения хотя бы одной задачи
    # удалим завершившиеся из списка
    for pid in "${PIDS[@]}"; do
      if ! kill -0 "$pid" 2>/dev/null; then
        PIDS=("${PIDS[@]/$pid}")
      fi
    done
  fi
done

wait
🔥 Такой подход позволяет:
📍 Делать умные очереди задач 📍 Балансировать нагрузку 📍 Экономить ресурсы 📍 Контролировать порядок и параллелизм
BashTex 📱 #bash

Bash-функции с возможностью изменять аргументы Когда ты передаешь переменные в функции - по умолчанию это копии, а не ссылки. Но с declare -n (aka nameref) можно менять переменные по ссылке, включая элементы массивов и даже динамические имена переменных. ❓ Что такое nameref? declare -n ref=имя - создает ссылку на переменную, позволяя функции менять её напрямую. ▪️ Пример: модификация значения по ссылке

modify() {
  declare -n ref=$1
  ref="Изменено внутри функции"
}

value="Оригинал"
modify value
echo "$value"  # Изменено внутри функции
▪️ Пример: изменение массива внутри функции

update_array() {
  declare -n arr=$1
  arr+=("новый элемент")
}

my_array=("один" "два")
update_array my_array
printf "%s\n" "${my_array[@]}"
Вывод:

один
два
новый элемент
▪️ Комбинирование с итерацией и позиционными аргументами

double_values() {
  declare -n numbers=$1
  for i in "${!numbers[@]}"; do
    numbers[$i]=$((numbers[$i] * 2))
  done
}

arr=(10 20 30)
double_values arr
echo "${arr[@]}"  # 20 40 60
❗️ Когда использовать nameref?
📍 Когда хочется возвращать несколько значений из функции 📍 Когда работаешь с динамическими именами переменных 📍 Когда пишешь библиотеки/модули на Bash
BashTex 📱 #bash #utils

Repost from Linux & Bash
📞 Знал ли ты, почему талисман Linux — пингвин? - В 1996 году Линус Торвальдс рассказал, что в детстве его клюнул пингвин в з
📞 Знал ли ты, почему талисман Linux — пингвин? - В 1996 году Линус Торвальдс рассказал, что в детстве его клюнул пингвин в зоопарке, и это оставило впечатление. Позже, выбирая символ для Linux, он решил, что пингвин — отличный вариант, ведь он «милый, но немного неуклюжий, как и ядро Linux в начале» Ставь 🔥 если тукс имба 👊 Linux & Bash | Подписаться

Автоматизация создания пользователя в Linux Каждый раз настраивать нового юзера вручную - скучно. Особенно если нужно: создать пользователя, выдать sudo, настроить SSH-доступ, прописать алиасы и окружение 🛠 Решается скриптом (create_user.sh):

#!/bin/bash

USERNAME="$1"
PUBKEY_URL="$2"  # URL к публичному ключу или путь к файлу

if [[ -z "$USERNAME" || -z "$PUBKEY_URL" ]]; then
  echo "Usage: $0 <username> <pubkey_url_or_file>"
  exit 1
fi

# 1. Создание пользователя
useradd -m -s /bin/bash "$USERNAME"

# 2. Добавление в sudoers
usermod -aG sudo "$USERNAME"

# 3. Настройка SSH
HOME_DIR="/home/$USERNAME"
mkdir -p "$HOME_DIR/.ssh"
chmod 700 "$HOME_DIR/.ssh"

# Подгружаем ключ
if [[ "$PUBKEY_URL" =~ ^http ]]; then
  curl -s "$PUBKEY_URL" -o "$HOME_DIR/.ssh/authorized_keys"
else
  cp "$PUBKEY_URL" "$HOME_DIR/.ssh/authorized_keys"
fi

chmod 600 "$HOME_DIR/.ssh/authorized_keys"
chown -R "$USERNAME:$USERNAME" "$HOME_DIR/.ssh"

# 4. Aliases и welcome message
cat <<EOF >> "$HOME_DIR/.bashrc"

# --- Custom Setup ---
alias ll='ls -alF'
alias gs='git status'
echo "Добро пожаловать, $USERNAME!" 
EOF

chown "$USERNAME:$USERNAME" "$HOME_DIR/.bashrc"

echo "[+] Пользователь $USERNAME создан и готов к работе!"
▪️ Пример использования:

./create_user.sh dev1 https://example.com/dev1.pub
или

./create_user.sh admin1 ~/.ssh/id_rsa.pub
Скрипт подходит для CI/CD, dev-серверов, временных пользователей или быстрого поднятия окружения в cloud-инстансах. BashTex 📱 #bash

🎉 РОЗЫГРЫШ: Бесплатное обучение от GigaDevOps — твой шанс войти в IT на 200к+! Ребята разыгрывают бесплатное место на обучен
🎉 РОЗЫГРЫШ: Бесплатное обучение от GigaDevOps  — твой шанс войти в IT на 200к+! Ребята разыгрывают  бесплатное место на обучении DevOps, а также скидки в 50% и 30%!  Учиться у GigaDevOps - это:  ➖Менторы из Т-Банка, Газпрома, Positive Tech. ➖Реальные кейсы, пет-проект для GitLab, 30+ собесов для Senior/Middle. ➖Без воды — только практика и навыки, которые реально нужны компаниям. Как участвовать? 👉 Вступить Telegram-канал, где проводится розыгрыш 👉  Оставить комментарий под постом 👉  Поставить пару реакций!  ВСЁ — вы участвуете!  P.S. А если хотите точно начать карьеру в DevOps - у них есть бесплатная консультация, на которой Вам обо всём расскажут. Для записи на неё заполните короткую форму.  Подробности о розыгрыше в закрепе ТГ-канала ребят, не упустите возможность начать новую карьеру или прокачаться до Senior! 

Когда спрашивают почему я выбрал Linux BashTex 📱 #юмор
Когда спрашивают почему я выбрал Linux BashTex 📱 #юмор

Локальное зеркало APT-репозитория с Bash и rsync Обновление пакетов без внешнего интернета - это реально. Если ты обслуживаешь несколько серверов в ограниченной сети (или хочешь ускорить установку и обновление пакетов), стоит создать локальное зеркало APT-репозитория. Это особенно полезно для оффлайн-установок, CI/CD-сборок или ситуаций с нестабильным интернетом. ❓ Что нужно?
📍 Утилита rsync 📍 Немного места на диске (от 50 ГБ и выше) 📍 Простой скрипт для синхронизации
🛠 Пример скрипта:

#!/bin/bash

# Базовые параметры
MIRROR="rsync://mirror.yandex.ru/ubuntu"
DEST="/srv/apt-mirror"
DIST="focal"
ARCH="amd64"
SECTIONS="main,restricted,universe,multiverse"

mkdir -p "$DEST"

rsync -av --delete \
  --include "dists/" \
  --include "dists/$DIST/" \
  --include "dists/$DIST/*" \
  --include "pool/" \
  --include "pool/*" \
  --exclude "*" \
  "$MIRROR/" "$DEST"
Это минимальный зеркальный снимок. При необходимости можно расширить под debian-security, updates и другие релизы. ▪️ Настройка локального клиента. Чтобы использовать зеркало, на других серверах пропиши в /etc/apt/sources.list:

deb [trusted=yes] file:///srv/apt-mirror focal main restricted universe multiverse
или через nginx:

deb http://mirror.local/ focal main restricted universe multiverse
▪️ Автоматизация. Добавь скрипт в cron или systemd-timer для ежедневной синхронизации:

0 4 * * * /usr/local/bin/apt-mirror-sync.sh
Локальное зеркало экономит трафик, ускоряет установку и даёт контроль над пакетами в изолированных окружениях. BashTex 📱 #bash #utils

Bash и двоичные данные: читаем, конвертируем, анализируем Bash - не только для текста. Иногда приходится парсить бинарные файлы, смотреть их содержимое, искать сигнатуры или работать с данными в base64. В арсенале есть несколько утилит: xxd, od, base64 - и ты удивишься, сколько они могут. ▪️ xxd - человекочитаемый hex-дамп

xxd /bin/ls | head
Вывод:

00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0300 3e00 0100 0000 b080 4000 0000 0000  ..>.......@.....
Ты сразу видишь: 1. Смещение (слева) 2. HEX-представление 3. ASCII-декод справа (если есть) Обратно в бинарник:

xxd -r dump.hex > recovered.bin
▪️ od - гибкий дампер

od -An -t x1 -v myfile.bin
Это дает HEX-дамп без смещений, только байты. Удобно для парсинга в скриптах.

od -An -t d2 myfile.bin
Читаем 2-байтные значения как целые числа. ▪️ base64 - кодирование/декодирование в текст. Когда бинарь нужно «перенести» в текст:

base64 /bin/bash > bash.b64
Обратно:

base64 -d bash.b64 > bash_restored
Будет полезно: - для пересылки двоичных файлов через API - вставки бинарных данных в JSON/YAML - генерации payload'ов ▪️ Проверка сигнатур файлов

head -c 4 somefile | xxd
Для ELF-файлов ожидается:

7f 45 4c 46  → .ELF
Можно использовать для определения типа файла без file. ⭐️ Бонус: сравнение бинарников

cmp -l file1.bin file2.bin
Выводит байты, которые отличаются, с их смещением. BashTex 📱 #bash #utils

Автоматическое обновление и перезапуск Docker-контейнеров при выходе новых образов Если ты используешь докер и хочешь держать свои контейнеры в актуальном состоянии без ручного docker pull + restart - этот пост для тебя. С помощью bash можно отслеживать обновления образа и автоматически перезапускать контейнер, если он устарел. 🌟 Принцип:
📍 Проверяем хэш локального и удалённого образа 📍 Если разные — обновляем образ 📍 Перезапускаем контейнер с теми же параметрами 📍 Логируем событие
🛠 Пример скрипта:

#!/bin/bash

IMAGE="nginx:latest"
CONTAINER="my-nginx"
LOG="/var/log/docker_autoupdate.log"

echo "[$(date)] Проверка образа $IMAGE" >> "$LOG"

# Получаем текущий локальный digest
LOCAL_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE" 2>/dev/null || echo "none")

# Обновляем образ
docker pull "$IMAGE" > /dev/null 2>&1

# Получаем новый digest
NEW_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE" 2>/dev/null || echo "none")

# Сравниваем
if [[ "$LOCAL_DIGEST" != "$NEW_DIGEST" ]]; then
    echo "[$(date)] Образ обновлён. Перезапуск контейнера $CONTAINER..." >> "$LOG"
    
    docker stop "$CONTAINER"
    docker rm "$CONTAINER"
    
    # Запуск с нужными параметрами — укажи свои!
    docker run -d --name "$CONTAINER" -p 80:80 "$IMAGE"
    
    echo "[$(date)] Контейнер перезапущен с новым образом." >> "$LOG"
else
    echo "[$(date)] Образ актуален. Перезапуск не требуется." >> "$LOG"
fi
▪️ Для автоматизации: Добавь скрипт в cron или systemd-timer, например, каждые 6 часов:

0 */6 * * * /usr/local/bin/docker-auto-update.sh
⭐️ Советы:
📍 Используй docker inspect для восстановления аргументов запуска, если параметры сложные. 📍Для нескольких контейнеров используй массивы и цикл.
BashTex 📱 #bash

Автоматическая генерация CHANGELOG из git log Если ты оформляешь релизы или просто хочешь видеть историю изменений красиво, не нужно писать CHANGELOG.md вручную. Bash + git log = автоматическая генерация понятного и читаемого списка коммитов по тегу или дате. 🛠 Простой changelog между тегами

#!/bin/bash

PREV_TAG=$(git describe --abbrev=0 --tags HEAD^)
CURRENT_TAG=$(git describe --tags)

echo "## Changelog: $PREV_TAG → $CURRENT_TAG" > CHANGELOG.md
git log "$PREV_TAG..$CURRENT_TAG" --pretty="* %s (%an)" >> CHANGELOG.md
▪️ Пример вывода:

## Changelog: v1.2.0 → v1.3.0
* Добавлен скрипт автообновления (admin)
* Фикс логирования ошибок в cron (dev)
* Обновлена документация (docs)
▪️ По дате: за последнюю неделю

git log --since="7 days ago" --pretty="* %h %s (%an)" > changelog_this_week.md
▪️ Возможные расширения:
📍 Группировка по типу коммита (feat, fix, chore) 📍 Сортировка по автору или дате 📍 Добавление ссылок на GitHub ([#123](https://github.com/...)) 📍 Генерация changelog на каждый git tag с сохранением в releases/
⭐️ Совет: Добавить в Makefile или release.sh:

changelog:
 bash scripts/gen_changelog.sh
И у тебя всегда будет свежий, читаемый список изменений для клиентов или команды. BashTex 📱 #bash

Управление каталогами через стек путей Все еще используешь cd туда-сюда, чтобы прыгать по директориям? Попробуй pushd и popd - это как cd, но умнее: команды работают со стеком путей, а значит ты можешь легко возвращаться обратно. 🌟 Как это работает
pushd /some/path - перейти в каталог и добавить его в стек. popd - вернуться назад по стеку и удалить текущий путь из него. dirs - показать текущий стек директорий.
▪️ Пример использования

pushd /etc/nginx
ls -l

pushd /var/log
tail -n 10 syslog

popd  # Возврат в /etc/nginx
popd  # Возврат туда, где были до первого pushd
Стек хранит историю твоих переходов, как назад в браузере. ▪️ dirs: просмотр пути

dirs -v
# 0  ~/project/scripts
# 1  ~/project
# 2  ~
Это означает: dirs +0 → текущий путь dirs +1 → предыдущий popd +1 → убрать второй элемент ❓ Где полезно:
1. В сложных скриптах, где ты переходишь между 3-4 директориями 2. При автоматизации сборки (build → temp → deploy → назад) 3. Когда нужно "вернуться" точно туда, откуда пришёл
⭐️ Совет: Добавить алиасы для удобства:

alias bd='popd'
alias pd='pushd'
alias d='dirs -v'
pushd/popd - это просто удобная альтернатива cd с историей. Попробуй - и не можешь не возвращаться к cd ../../../.. BashTex 📱 #bash #utils

😏 BashTex 📱 #юмор
😏 BashTex 📱 #юмор

Автогенерация help/usage в Bash Одна из лучших практик при написании bash-утилит - добавлять --help, чтобы объяснять, как работает скрипт. Но зачем дублировать описание в заголовке и в коде, если можно использовать один и тот же блок? С помощью cat <<EOF и sed можно генерировать справку прямо из комментариев скрипта. 🛠 Пример структуры скрипта:

#!/bin/bash

: <<'USAGE'
my-script.sh - полезный инструмент

Использование:
  ./my-script.sh [опции]

Опции:
  -h        показать помощь
  -f FILE   указать файл
  -v        включить подробный вывод

Пример:
  ./my-script.sh -f config.ini -v
USAGE

# Генерация help из заголовка
show_help() {
  sed -n "/^: <<'USAGE'/,/^USAGE/p" "$0" | sed '1d;$d'
}

while getopts ":hf:v" opt; do
  case $opt in
    h) show_help; exit 0 ;;
    f) FILE=$OPTARG ;;
    v) VERBOSE=1 ;;
    \?) echo "Неверный флаг: -$OPTARG" >&2; show_help; exit 1 ;;
  esac
done
⭐️ Как это работает?
📍 : <<'USAGE' ... USAGE - это многострочный комментарий. 📍 sed -n '/^: <<'\''USAGE'\''/,/^USAGE/p' "$0" - извлекает его. 📍 В show_help() мы красиво выводим только нужный блок.
Теперь ты всегда видишь usage в начале файла - и это единственный источник правды. BashTex 📱 #bash #utils

Игроман или что? 🤔 BashTex 📱 #юмор
Игроман или что? 🤔 BashTex 📱 #юмор

Управление процессами после разрыва сессии Бывало такое: запустил долгую задачу, закрыл терминал - и всё пропало. А что если процесс всё ещё жив, и ты можешь снова им управлять? Сегодня разберём два инструмента: ts - из moreutils для запуска с timestamp reptyr - для перехвата уже запущенного процесса и перевода его обратно в терминал 🌟 Сценарий: восстановление "осиротевшего" процесса 1️⃣ Запустили задачу без screen или tmux:

some-heavy-task.sh &
2️⃣ Вышли из терминала, но процесс живёт (можно найти через ps или top). 3️⃣ Подключаемся обратно, узнаём PID:

ps aux | grep some-heavy-task
4️⃣ Забираем процесс себе:

reptyr <PID>
Теперь процесс снова управляем - можно читать вывод, отменить Ctrl+C, передать сигналы. ⚙️ Установка

sudo apt install reptyr moreutils  # Ubuntu/Debian
sudo yum install reptyr moreutils  # RHEL/CentOS
🔥 ts - лог с таймштампами. Хочешь узнать, когда именно что-то произошло в логе?

long-running-command | ts '[%Y-%m-%d %H:%M:%S]'
Пример вывода:

[2025-06-10 10:03:10] Запущено обновление системы
[2025-06-10 10:03:25] Завершено без ошибок
Идеально для cron-скриптов, CI-логов и мониторинга. ❗️ Ограничения и советы 📍 reptyr не всегда работает, если у процесса есть PTY или взаимодействие с stdin. 📍 Чтобы reptyr работал на Ubuntu 20+ - нужно отключить Yama security:

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
(для постоянства: добавь в /etc/sysctl.d/10-ptrace.conf) BashTex 📱 #bash #utils

Анализ активности пользователей через .bash_history Если ты хочешь узнать, кто чем занимался на сервере, не прибегая к сложным средствам аудита - начни с простого: разбор ~/.bash_history. Это быстрый способ получить отчёт об активности пользователей, особенно если логи команд не централизуются. ❓ Что можно узнать:
📍Самые часто используемые команды 📍Подозрительные или потенциально опасные действия 📍Время последней активности (если HISTTIMEFORMAT включён) 📍Кто запускал sudo, rm, curl, scp и прочие «чувствительные» команды
🛠 Пример скрипта:

#!/bin/bash

REPORT="/tmp/history_report.txt"
KEY_CMDS="sudo|rm|curl|scp|wget|nc|nmap|python|ssh|dd"

echo "Отчёт об активности пользователей - $(date)" > "$REPORT"
echo >> "$REPORT"

for user_home in /home/*; do
  user=$(basename "$user_home")
  hist_file="$user_home/.bash_history"

  [[ -f "$hist_file" ]] || continue

  echo "Пользователь: $user" >> "$REPORT"
  echo "— Топ 5 команд:" >> "$REPORT"
  grep -v '^#' "$hist_file" | awk '{print $1}' | sort | uniq -c | sort -rn | head -n 5 >> "$REPORT"

  echo "— Подозрительные команды:" >> "$REPORT"
  grep -E "$KEY_CMDS" "$hist_file" | tail -n 5 >> "$REPORT"
  echo >> "$REPORT"
done

cat "$REPORT"
▪️ Проверка root-пользователя:

grep -E "$KEY_CMDS" /root/.bash_history | tail -n 5
А если у вас включён HISTTIMEFORMAT, можно дополнительно привязать команды к датам. 🌟 Этот простой анализ позволяет выявить:
- кто часто использует sudo, rm -rf, dd - несанкционированную установку пакетов (apt install, curl | bash) - запуск сетевых туннелей (ssh -R, ngrok, socat)
BashTex 📱 #security

IT-челлендж Слёрма — проверь свой скилл! 5 дней — 5 тем для IT-инженеров уровня Middle: ▪️ Bash / Linux / DevOps ▪️ Сети ▪️ C
IT-челлендж Слёрма — проверь свой скилл! 5 дней — 5 тем для IT-инженеров уровня Middle: ▪️ Bash / Linux / DevOps ▪️ Сети ▪️ CI/CD, Docker, Jenkins ▪️ SQL и базы данных ▪️ Информационная безопасность 🔺Короткие, но умные задания в Google Формах 🔺Удобный Telegram-бот ведёт по шагам 🔺Занимает не больше 15–20 минут в день Подарки победителям: Подписка на курсы Слёрма Курс «Администрирование Linux» Курс «Ansible: Infrastructure as Code» 🎫 30% скидка всем, кто дойдёт до конца 📅 Челлендж с 16 по 20 июня 📍 Регистрация в боте до 15 июня

Это был неправильный ответ, подумай еще BashTex 📱 #юмор
Это был неправильный ответ, подумай еще BashTex 📱 #юмор

Контроль целостности /usr/bin — базовая защита от подмены Один из простых, но эффективных способов обнаружить компрометацию системы - сравнение контрольных сумм бинарей с эталонным списком. Если кто-то подменил ls, sudo или ssh, мы это заметим. 1️⃣ Создание whitelist-файла. Собираем хеши всех бинарников в /usr/bin:

find /usr/bin -type f -executable -exec sha256sum {} \; > /root/usrbin.sha256
Лучше делать это на только что установленной и проверенной системе. 2️⃣ Скрипт для проверки целостности

#!/bin/bash
WHITELIST="/root/usrbin.sha256"
LOG="/var/log/usrbin_integrity_check.log"
TMP=$(mktemp)

echo "[INFO] Проверка целостности /usr/bin — $(date)" >> "$LOG"

find /usr/bin -type f -executable -exec sha256sum {} \; > "$TMP"
DIFF=$(diff -u "$WHITELIST" "$TMP")

if [[ -n "$DIFF" ]]; then
    echo "[ALERT] Обнаружены изменения!" >> "$LOG"
    echo "$DIFF" >> "$LOG"
else
    echo "[OK] Изменений не найдено." >> "$LOG"
fi

rm "$TMP"
Не забудьте сделать его исполняемым:

chmod +x /usr/local/bin/check_usrbin.sh
3️⃣ Настройка периодической проверки. Добавьте cron-задание:

sudo crontab -e
И вставить:

0 3 * * * /usr/local/bin/check_usrbin.sh
Проверка будет происходить каждый день в 03:00, лог - в /var/log/usrbin_integrity_check.log. ⭐️ Что ещё можно сделать:
- Добавить /usr/sbin, /bin, /sbin — аналогично. - Сравнивать не только hash, но и размер, время изменения (через stat). - Использовать aide или tripwire для более продвинутого контроля.
BashTex 📱 #security

Ротационные бэкапы с экономией места: rsync + hardlink На сервере делаются ежедневные резервные копии, но не хочется тратить кучу места на дублирование одних и тех же файлов? Есть отличный способ - использовать rsync с жёсткими ссылками (hardlinks) для дедупликации. Это позволяет хранить полные снепшоты, при этом экономя место. 🌟 Суть подхода Бэкапы выглядят как отдельные директории (backup-2025-06-02, backup-2025-06-01), но все неизмененные файлы - это просто ссылки на одни и те же иноды. Если файл не изменился - он физически не дублируется, а просто переиспользуется в новом бэкапе. ▪️ Структура и логика Пример каталогов:

/backups/
├── daily.0    ← сегодня
├── daily.1    ← вчера
├── daily.2
└── daily.3
daily.0 - свежий бэкап. daily.1, daily.2, ... - предыдущие снепшоты. При каждом новом запуске: старые бэкапы смещаются на +1 (daily.2 → daily.3) daily.0 создаётся как --link-dest от daily.1 ▪️ Скрипт ротационного бэкапа

#!/bin/bash

SRC="/home/user"
DEST="/backups"
MAX=7  # сколько дней хранить

# Сдвигаем старые бэкапы
for ((i=MAX-1; i>=0; i--)); do
    if [ -d "$DEST/daily.$i" ]; then
        mv "$DEST/daily.$i" "$DEST/daily.$((i+1))"
    fi
done

# Создаём новый бэкап с дедупликацией
LINK=""
if [ -d "$DEST/daily.1" ]; then
    LINK="--link-dest=$DEST/daily.1"
fi

rsync -aAX --delete $LINK "$SRC/" "$DEST/daily.0"
⭐️ Преимущества
- Каждый бэкап - полный, можно восстановить всё в конкретном состоянии. - Экономия места - используется только дополнительное место для новых/изменённых файлов. - Простота восстановления: rsync обратно или просто cp.
BashTex 📱 #bash #utils