en
Feedback
BashTex | Linux

BashTex | Linux

Open in Telegram

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

Show more
2 521
Subscribers
+124 hours
+17 days
-1130 days
Posts Archive
Проверка архивов на целостность: избегаем битых бэкапов Создавать бэкапы - хорошая практика. Но что, если архив оказался битым в самый нужный момент? 😱 Разберемся, как проверять целостность архивов, чтобы не потерять важные данные. 1️⃣ Проверка tar-архива. Если архив создавался с помощью tar, его можно проверить без распаковки:

tar -tvf backup.tar.gz
Если файл поврежден, команда выдаст ошибку:

gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now
🧑‍💻 Автоматическая проверка в скрипте:

if tar -tzf backup.tar.gz &>/dev/null; then
    echo "Архив исправен"
else
    echo "Архив поврежден!"
fi
2️⃣ Проверка архивов .zip. Для .zip можно использовать встроенную проверку:

unzip -t backup.zip
Если файл битый, команда выдаст ошибки. 🧑‍💻 Автоматическая проверка в скрипте:

if unzip -t backup.zip | grep -q "No errors detected"; then
    echo "Архив исправен"
else
    echo "Архив поврежден!"
fi
3️⃣ Проверка и автоматическое исправление rar. Если архив в формате .rar, его можно проверить так:

rar t backup.rar
Если архив поврежден, rar может попытаться его восстановить:

rar r backup.rar
4️⃣ Защита от битых архивов при создании 📁 Контрольные суммы. Считаем SHA256-хеш перед передачей или копированием:

sha256sum backup.tar.gz > backup.sha256
А потом проверяем:

sha256sum -c backup.sha256
📦 Двойная упаковка с тестированием

tar -cvf - logs/ | gzip | tee backup.tar.gz | gzip -t
📌 Здесь tee дублирует поток, а gzip -t сразу проверяет целостность. BashTex 📱 #linux #utils

Обработка многомерных массивов и ассоциативных списков в Bash Bash не поддерживает многомерные массивы на уровне языка, но это не мешает нам создавать их с помощью ассоциативных массивов или хитрых обходных путей. Сегодня про то, как это сделать. 1️⃣ Ассоциативные массивы как таблицы. С Bash 4+ появились ассоциативные массивы (declare -A), что позволяет организовать данные в виде таблицы:

declare -A users

users["user1,name"]="Egor"
users["user1,age"]=25
users["user2,name"]="Ivan"
users["user2,age"]=30

echo "Имя user1: ${users["user1,name"]}"  # Egor
echo "Возраст user2: ${users["user2,age"]}"  # 30
📌 Мы используем ключи вида userX,property, чтобы эмулировать двумерную структуру. 2️⃣ Многомерные массивы через вложенные списки. Если нужно хранить массив внутри массива, можно использовать строки с разделителем:

declare -A servers

servers["db"]="192.168.1.10:5432:PostgreSQL"
servers["web"]="192.168.1.20:80:Nginx"

IFS=":" read -r ip port service <<< "${servers["db"]}"
echo "Сервер базы: IP=$ip, Порт=$port, Сервис=$service"
📌 Здесь IFS=":" read -r ... разбивает строку на переменные. 3️⃣ Итерация по многомерной структуре. Перебираем всех пользователей и их данные:

for key in "${!users[@]}"; do
    echo "$key -> ${users[$key]}"
done
📌 !users[@] возвращает список всех ключей. 4️⃣ JSON-подход с jq. Если сложность растет, лучше работать с JSON:

json='{"user1": {"name": "Egor", "age": 25}, "user2": {"name": "Ivan", "age": 30}}'

echo "$json" | jq '.user1.name'  # Egor
BashTex 📱 #linux #utils

basename и dirname: неочевидные сценарии работы с путями Команды basename и dirname - инструменты для работы с файловыми путями в Bash. Они часто используются в скриптах, но не все знают о неочевидных возможностях. Разбираемся! 1️⃣ Быстрая обработка путей

file_path="/var/log/nginx/access.log"

echo "Файл: $(basename "$file_path")"  # access.log
echo "Каталог: $(dirname "$file_path")"  # /var/log/nginx
🔹 basename извлекает имя файла 🔹 dirname оставляет только путь к каталогу 2️⃣ Работа с расширениями. Можно удалить расширение файла с помощью basename:

basename "/home/user/script.sh" .sh  # Выведет: script
📌 Это полезно, например, при генерации логов:

log_file="$(basename "$0" .sh).log"
echo "Логи пишем в $log_file"
💡 Здесь $0 - имя запущенного скрипта. 3️⃣ Разбор путей без / в конце. Если путь оканчивается на /, dirname может вернуть неожиданный результат:

dirname "/etc/nginx/"  # Выведет: /etc
dirname "/etc/nginx"   # Выведет: /etc
📌 Чтобы избежать проблем, лучше заранее удалять слеши:

path="/etc/nginx/"
dirname "${path%/}"  # /etc/nginx
4️⃣ Разделение относительных и абсолютных путей. Хотим понять, абсолютный ли путь передан в скрипт?

path="./script.sh"

if [[ "$(dirname "$path")" == "." ]]; then
    echo "Это относительный путь"
else
    echo "Это абсолютный путь"
fi
5️⃣ Комбинируем с find и xargs. Переименовываем все .txt файлы в .bak, сохраняя имена:

find /path/to/files -name "*.txt" | while read file; do
    mv "$file" "$(dirname "$file")/$(basename "$file" .txt).bak"
done
📌 Здесь basename убирает .txt, а dirname сохраняет путь. BashTex 📱 #linux #utils

С планами на вечер определились ❤️ BashTex 📱 #юмор

Циклы с подсчётом времени выполнения: оптимизация итераций При написании Bash-скриптов важно не только выполнять задачи, но и делать это максимально эффективно. Разберемся, как можно замерять время выполнения циклов и оптимизировать их. 1. Измерение времени выполнения. Для базового замера используем команду time. Пример простого for-цикла:

time for i in {1..10000}; do echo -n; done

real    0m0.245s
user    0m0.190s
sys     0m0.055s
real - общее время выполнения user - время, потраченное процессором на выполнение кода sys - время, потраченное на системные вызовы 2. Оптимизация цикла. Допустим, у нас есть for-цикл, выполняющий сложные вычисления:

start=$(date +%s)  # Засекаем время начала

for i in {1..1000}; do
    echo $((i * i)) > /dev/null  # Квадрат числа
done

end=$(date +%s)  # Засекаем время окончания
echo "Время выполнения: $((end - start)) секунд"
Но можно ускорить этот процесс! Оптимизация с seq и awk:

time seq 1 1000 | awk '{print $1 * $1}' > /dev/null
Результат: Использование awk снижает нагрузку на bash, так как он быстрее работает с числами. 3. Запуск в параллельном режиме. Для ещё большего ускорения используем xargs -P:

time seq 1 1000 | xargs -P 4 -I {} bash -c 'echo $(( {} * {} ))' > /dev/null
-P 4 запускает 4 параллельных процесса, ускоряя обработку данных. BashTex 📱 #bash #utils

Быстрая настройка GitLab CI/CD для проектов Автоматизация сборки, тестирования и развертывания - важный шаг в DevOps. GitLab CI/CD позволяет быстро организовать процесс CI/CD с минимальными затратами. 1. Подготовка GitLab Runner. Перед запуском CI/CD необходимо настроить GitLab Runner — агент, выполняющий задачи в пайплайне. Установка и регистрация GitLab Runner:

# Устанавливаем GitLab Runner
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt install gitlab-runner -y

# Регистрируем Runner в GitLab
sudo gitlab-runner register \
  --url "https://gitlab.com/" \
  --registration-token "ВАШ_ТОКЕН" \
  --executor "docker" \
  --docker-image "alpine:latest"
Токен можно найти в разделе Settings → CI/CD → Runners в GitLab. 2. Создание .gitlab-ci.yml. Файл .gitlab-ci.yml описывает все стадии CI/CD. Простейший вариант:

stages:
  - build
  - test
  - deploy

build:
  stage: build
  script:
    - echo "Сборка проекта..."
    - make build  # Команда сборки

test:
  stage: test
  script:
    - echo "Запуск тестов..."
    - make test  # Запуск тестов

deploy:
  stage: deploy
  script:
    - echo "Деплой на сервер..."
    - rsync -avz ./project user@server:/var/www/project
  only:
    - main  # Деплой только из ветки main
🔗 Что тут происходит? build - сборка проекта test - запуск тестов deploy - деплой на сервер (например, с помощью rsync) 3. Запуск и отладка. После коммита .gitlab-ci.yml в репозиторий GitLab автоматически запустит пайплайн. Просмотр логов сборки: Перейдите в "CI/CD → Pipelines", выберите нужный пайплайн и смотрите логи выполнения. Отладка вручную: Можно запустить локальный Runner для проверки:

gitlab-runner exec shell test
BashTex 📱 #utils

Динамическая замена строк в переменных без внешних утилит В Bash многие привыкли использовать sed, awk или tr для замены текста, но можно обойтись без них, используя встроенные механизмы обработки строк 1. Простая замена в строке. Стандартная конструкция:

text="Hello, world!"
echo "${text/world/Bash}"
Вывод: Hello, Bash! Здесь world заменяется на Bash. 2. Замена всех вхождений. Если слово встречается несколько раз, можно заменить все его появления:

text="apple banana apple orange"
echo "${text//apple/grape}"
Вывод: grape banana grape orange Обратите внимание на // — оно заменяет все вхождения. 3. Удаление подстроки. Чтобы удалить слово из строки, просто оставьте замену пустой:

text="error: file not found"
echo "${text/error: /}"
Вывод: file not found 4. Замена только в начале или конце строки. Замена в начале строки:

text="error_log_123"
echo "${text/#error_/warn_}"
Вывод: warn_log_123 Замена в конце строки:

text="backup_20240101.tar"
echo "${text/%tar/gz}"
Вывод: backup_20240101.gz 5. Динамическая замена значений в переменных. Допустим, у нас есть путь, и мы хотим заменить часть его на другую:

path="/home/user/project/file.txt"
new_path="${path/user/admin}"
echo "$new_path"
Вывод: /home/admin/project/file.txt 6. Усложненный пример: замена динамических данных. Предположим, у нас есть строка с датой, и мы хотим заменить год на текущий:

text="Backup from 2023-05-01"
current_year=$(date +%Y)
echo "${text/2023/$current_year}"
Вывод (если 2025 год): Backup from 2025-05-01 BashTex 📱 #linux #utils

Автономное восстановление сетевого соединения при сбоях Что делать, если сервер внезапно теряет соединение? Вручную перезапускать сетевой интерфейс? Можно автоматизировать этот процесс. 1. Простая проверка доступности сети. Начнем с базового скрипта, который проверяет соединение и перезапускает сеть, если пинг не проходит.

#!/bin/bash

TARGET="8.8.8.8"  # IP-адрес для проверки (Google DNS)
INTERFACE="eth0"  # Ваш сетевой интерфейс

if ! ping -c 4 $TARGET &> /dev/null; then
    echo "$(date) - Потеряно соединение! Перезапускаю сеть..." >> /var/log/network_recovery.log
    systemctl restart networking
    systemctl restart NetworkManager  # Для дистрибутивов с NetworkManager
    ip link set $INTERFACE down && sleep 2 && ip link set $INTERFACE up
else
    echo "$(date) - Сеть работает нормально" >> /var/log/network_recovery.log
fi
🔗 Как работает: Пингует 8.8.8.8 (можно заменить на свой сервер). Если нет ответа, записывает событие в лог и перезапускает сетевой интерфейс. Если сеть работает, просто пишет статус в лог. Автозапуск каждые 5 минут: Добавьте в crontab:

*/5 * * * * /path/to/network_check.sh
2. Авто-переключение на резервный интерфейс. Если ваш сервер поддерживает несколько сетевых интерфейсов (например, eth0 и eth1), можно автоматически переключаться на резервный:

#!/bin/bash

TARGET="8.8.8.8"
PRIMARY_IF="eth0"
SECONDARY_IF="eth1"

if ! ping -c 4 $TARGET &> /dev/null; then
    echo "$(date) - Основной интерфейс $PRIMARY_IF не отвечает, переключаюсь на $SECONDARY_IF" >> /var/log/network_recovery.log
    ip route del default
    ip route add default via 192.168.1.2 dev $SECONDARY_IF
else
    echo "$(date) - Основной интерфейс $PRIMARY_IF работает" >> /var/log/network_recovery.log
fi
🔗 Как работает: Если основной интерфейс не отвечает, переключается на резервный. Изменяет маршрут по умолчанию на резервное подключение. 3. Авто-переключение на резервный VPN. Если ваш сервер использует VPN, можно автоматически переключаться между провайдерами:

#!/bin/bash

VPN_PRIMARY="vpn1"
VPN_SECONDARY="vpn2"

if ! ping -c 4 10.8.0.1 &> /dev/null; then
    echo "$(date) - Основной VPN не отвечает, переключаюсь на резервный $VPN_SECONDARY" >> /var/log/network_recovery.log
    systemctl restart openvpn@$VPN_SECONDARY
else
    echo "$(date) - VPN работает стабильно" >> /var/log/network_recovery.log
fi
🔗 Как работает: Проверяет доступность VPN (например, 10.8.0.1). Если основной VPN не отвечает, переключается на резервный сервер. BashTex 📱 #bash

LS как инструмент для сортировки и поиска Обычно ls используют просто для вывода списка файлов, но на самом деле эта команда умеет больше - она может сортировать, фильтровать и даже помогать в поиске нужных данных. Разберем варианты использования. 1. Сортировка файлов по размеру. Хотите быстро найти самый тяжелый файл в каталоге? Используйте:

ls -lhS
-l - детальный вывод (размер, права, дата) -h - удобный человекочитаемый формат (KB, MB, GB) -S - сортировка по размеру (от большего к меньшему)
Если хотите отсортировать в обратном порядке (от меньшего к большему), добавьте -r:

ls -lhSr
2. Сортировка по времени изменения. Чтобы узнать, какие файлы менялись последними, используйте:

ls -lt
-t - сортировка по времени изменения Если хотите узнать, какие файлы были доступны (прочитаны) последними:

ls -lu
А для сортировки по времени создания (если поддерживается файловой системой):

ls -lU
3. Поиск файлов с определенными характеристиками По расширению. Найти все .log файлы:

ls *.log
По размеру (совместно с grep). Например, найти все файлы больше 100MB:

ls -lhS | grep '[0-9][0-9][0-9]M'
Фильтрация директорий. Только каталоги (без файлов):

ls -d */
4. Использование цветных фильтров. Хочется визуально выделять файлы по типу? Используйте:

ls --color=auto
Для более детальной настройки цветов можно изменить переменную LS_COLORS:

export LS_COLORS="di=34;1:fi=0:ln=36;1:ex=32;1"
di=34;1 - каталоги (синий) ln=36;1 - символические ссылки (голубой) ex=32;1 - исполняемые файлы (зеленый)
5. Совместное использование с другими командами. Команда ls хорошо сочетается с head, tail и sort: Найти самый старый файл

ls -lt | tail -n 1
Отобразить файлы, отсортированные по имени без учета регистра

ls -l | sort -f
BashTex 📱 #linux #utils

Ну мы BashTex 📱 #юмор
Ну мы BashTex 📱 #юмор

Прерывание работы скрипта с сохранением прогресса При выполнении долгих скриптов (например, обработки данных или резервного копирования) важно предусмотреть механизм безопасного прерывания с возможностью продолжения с того места, где процесс остановился. Сегодня про то, как можно организовать такую систему в Bash с использованием файлов-снапшотов. Файл-снапшот хранит состояние выполнения скрипта. При запуске скрипт проверяет наличие этого файла, чтобы понять, нужно ли продолжить работу или начать заново. 💡 Реализация Предположим, у нас есть список файлов для обработки. Скрипт будет:
Чтить файл-снапшот, чтобы определить, с какого места продолжить. Обрабатывать файлы по одному. Обновлять прогресс в snap-файле.

#!/bin/bash

# Имя файла-снапшота
SNAPSHOT_FILE="progress.snapshot"

# Список задач (например, файлы для обработки)
FILES=("file1.txt" "file2.txt" "file3.txt" "file4.txt" "file5.txt")

# Чтение текущего прогресса из снапшота
CURRENT_INDEX=0
if [[ -f $SNAPSHOT_FILE ]]; then
  CURRENT_INDEX=$(<"$SNAPSHOT_FILE")
  echo "Прогресс найден: начнем с файла ${FILES[$CURRENT_INDEX]}"
else
  echo "Снапшот не найден: начнем сначала"
fi

# Обработка файлов
for ((i=CURRENT_INDEX; i<${#FILES[@]}; i++)); do
  echo "Обрабатываю ${FILES[$i]}..."
  
  # Имитация долгой обработки
  sleep 2
  
  echo "Файл ${FILES[$i]} обработан!"
  
  # Обновление прогресса в файле-снапшоте
  echo $((i + 1)) > "$SNAPSHOT_FILE"
done

# Удаление снапшота после завершения работы
rm -f "$SNAPSHOT_FILE"
echo "Все файлы обработаны, прогресс очищен!"
Примеры вывода Первый запуск:

Снапшот не найден: начнем сначала
Обрабатываю file1.txt...
Файл file1.txt обработан!
Обрабатываю file2.txt...
Файл file2.txt обработан!
...
Если прервать выполнение, то прогресс сохранится в progress.snapshot. Повторный запуск:

Прогресс найден: начнем с файла file3.txt
Обрабатываю file3.txt...
Файл file3.txt обработан!
...
🔎 Обработка ошибок Чтобы обеспечить надежность:
Проверяйте, существует ли файл перед обработкой. Используйте команды trap для удаления временных файлов при непредвиденных ошибках. Логируйте результаты обработки.

trap 'rm -f $SNAPSHOT_FILE; echo "Ошибка! Прогресс сохранен.";' SIGINT SIGTERM
🔗 Расширенная версия: поддержка нескольких процессов Для обработки в несколько потоков можно использовать отдельные снапшоты для каждой задачи. Например:

for file in "${FILES[@]}"; do
  {
    if [[ ! -f "${file}.done" ]]; then
      echo "Обрабатываю $file..."
      sleep 2  # Имитация обработки
      echo "Файл $file обработан!"
      touch "${file}.done"
    fi
  } &
done
wait
Файлы-снапшоты - простой, но важный инструмент для повышения надежности скриптов. Они позволяют безопасно прерывать и продолжать выполнение, экономя ваше время. BashTex 📱 #bash #utils

Все надоело и пропал интерес, чувствуешь себя амебой и хочется только залипать в телефоне. Бывает? Психолог взрослого человек
Все надоело и пропал интерес, чувствуешь себя амебой и хочется только залипать в телефоне. Бывает? Психолог взрослого человека - канал для айтишников, у которых периодически опускаются руки и отключается мозг, ибо переработки и постоянная тревожность не приводят к другим исходам. ✔️ Как научиться отвлекаться от работы и отдыхать? ✔️ Как совместить кучу рабочих задач и время с семьей? ✔️ Как справиться с прокрастинацией? ✔️ Как не растерять запал, даже если кажется, что ничего не выходит? Подписывайтесь на канал @vadimpetrov_psy и научитесь работать без упахивания, выгорания и ущерба для личной жизни! 👨🏻‍💻 Псс. Заходите в закреп канала - там много полезного, и даже бесплатный мини-курс.

Динамическое распределение нагрузки между серверами на основе сетевого трафика ⚙️ Как это работает? Балансировщики нагрузки анализируют входящий трафик, измеряют метрики серверов (задержки, использование ресурсов) и динамически перенаправляют запросы к менее загруженным узлам. Основные механизмы:
Текущий сетевой трафик: оценивается объём данных, проходящих через сервер. Задержка отклика: запросы направляются к серверу с минимальной задержкой. Уровень нагрузки CPU/RAM: запросы равномерно распределяются между серверами, исходя из их состояния.
Инструменты для реализации 1. HAProxy. HAProxy - высокопроизводительный балансировщик нагрузки. Он поддерживает динамическое распределение на основе метрик. Настройка:

sudo apt update && sudo apt install haproxy
Фрагмент конфигурации /etc/haproxy/haproxy.cfg:

frontend http_front
    bind *:80
    default_backend servers

backend servers
    balance leastconn
    server srv1 192.168.1.101:80 check
    server srv2 192.168.1.102:80 check
Здесь запросы направляются серверу с наименьшим числом соединений (leastconn). 2. NGINX. NGINX также можно использовать как балансировщик. Он поддерживает модули для анализа времени отклика. Пример конфигурации:

upstream backend {
    server 192.168.1.101 max_fails=3 fail_timeout=30s;
    server 192.168.1.102 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }
}
Дополнительный модуль ngx_http_healthcheck_module позволяет учитывать время отклика серверов. 3. Traefik. Современное решение для балансировки в облачных и контейнерных средах. Traefik автоматически подхватывает информацию о серверах из Docker или Kubernetes. BashTex 📱 #linux #utils

Управление очередями фоновых задач в Bash с помощью функций и переменных При работе с большими скриптами в Linux нередко требуется запускать задачи в фоновом режиме. Но чтобы всё работало корректно, нужно уметь управлять очередями задач. Сейчас разберемся, как организовать очередь фоновых задач с использованием функций и переменных, чтобы избежать перегрузки системы. 🛠 Что нужно знать о фоновых задачах? В Bash можно запускать процессы в фоне, добавляя & в конце команды. Но если одновременно запущено слишком много процессов, система может потерять стабильность. Управление очередью фоновых задач позволяет:
Ограничить количество одновременно выполняемых задач. Следить за состоянием задач. Организовать приоритет выполнения.
Реализация очереди задач 1. Пример базового скрипта с ограничением задач. Этот скрипт запускает фоновые задачи, ограничивая их количество:

#!/bin/bash

# Максимальное количество фоновых задач
MAX_JOBS=4

# Функция для ожидания завершения задач
wait_for_jobs() {
  while (( $(jobs -r | wc -l) >= MAX_JOBS )); do
    sleep 1
  done
}

# Функция, которая будет выполняться в фоне
task() {
  local id=$1
  echo "Task $id started"
  sleep $((RANDOM % 5 + 1))  # Имитация выполнения
  echo "Task $id completed"
}

# Основной цикл
for i in {1..10}; do
  wait_for_jobs  # Ожидание освобождения очереди
  task "$i" &    # Запуск задачи в фоне
done

# Ожидание завершения всех задач
wait
echo "All tasks completed!"
Вывод:

Task 1 started
Task 2 started
Task 3 started
Task 4 started
Task 1 completed
Task 5 started
Task 2 completed
Task 6 started
...
All tasks completed!
При выполнении скрипта можно увидеть, что одновременно запускается не более четырёх задач: 2. Улучшение с приоритетами и динамическим управлением Добавление приоритетов. Мы можем использовать массивы для хранения задач с разным приоритетом.

#!/bin/bash

MAX_JOBS=3
PRIORITY_TASKS=("High1" "High2")
NORMAL_TASKS=("Normal1" "Normal2" "Normal3")

wait_for_jobs() {
  while (( $(jobs -r | wc -l) >= MAX_JOBS )); do
    sleep 1
  done
}

task() {
  local name=$1
  echo "Task $name started"
  sleep $((RANDOM % 5 + 2))
  echo "Task $name completed"
}

# Выполнение задач с приоритетом
for task_name in "${PRIORITY_TASKS[@]}" "${NORMAL_TASKS[@]}"; do
  wait_for_jobs
  task "$task_name" &
done

wait
echo "All prioritized tasks completed!"
Задачи с приоритетом выполняются в первую очередь, вывод:

Task High1 started
Task High2 started
Task Normal1 started
Task High1 completed
Task Normal2 started
...
All prioritized tasks completed!
3. Дополнительные трюки: управление через переменные Динамическое добавление задач в очередь. Очередь можно заполнять динамически, используя массив:

#!/bin/bash

MAX_JOBS=4
TASK_QUEUE=()

# Функция добавления задач в очередь
add_task() {
  TASK_QUEUE+=("$1")
}

# Функция выполнения задач из очереди
process_queue() {
  for task_name in "${TASK_QUEUE[@]}"; do
    wait_for_jobs
    task "$task_name" &
  done
}

# Добавляем задачи в очередь
add_task "Task1"
add_task "Task2"
add_task "Task3"
add_task "Task4"
add_task "Task5"

# Обрабатываем очередь
process_queue
wait
echo "Dynamic queue processing completed!"
Преимущества такого подхода:
Контроль над нагрузкой на систему. Возможность задания приоритетов выполнения. Легкость добавления задач в реальном времени. Масштабируемость для больших скриптов.
BashTex 📱 #bash #utils

find + exec: создание цепочек команд в одном вызове find - это утилита для поиска файлов и директорий, а с опцией -exec она превращается в инструмент для выполнения сложных операций над найденными объектами. Вместо множества вызовов команд можно всё сделать в одной строке. Разберём интересные примеры. Базовый пример. Удалим все файлы .tmp в директории и её подкаталогах:

find /path/to/dir -name "*.tmp" -exec rm {} \;
{} - это подстановка имени файла. \; - завершает команду -exec. 1. Замена текста в файлах. Найдём файлы .txt и заменим в них все вхождения слова "TODO" на "DONE":

find /path/to/dir -name "*.txt" -exec sed -i 's/TODO/DONE/g' {} \;
Теперь все файлы обновлены автоматически! 2. Сжатие найденных файлов. Архивируем все .log файлы старше 7 дней:

find /var/log -name "*.log" -mtime +7 -exec gzip {} \;
3. Сложные операции с несколькими командами. Передача результата одной команды в другую возможна через sh -c:

find /path/to/dir -name "*.conf" -exec sh -c 'mv "$1" "${1%.conf}.bak"' _ {} \;
Здесь мы меняем расширение всех файлов .conf на .bak. 4. Параллельное выполнение с +. Если обработка большого числа файлов занимает много времени, используйте + вместо \; для выполнения команд за один вызов:

find /path/to/dir -name "*.log" -exec rm {} +
Это значительно ускоряет выполнение, передавая несколько файлов в один вызов rm. 5. Просмотр перед выполнением. Всегда проверяйте результат поиска перед выполнением команд:

find /path/to/dir -name "*.log" -exec echo "Удаляю: {}" \;
Это один из способов убедиться, что вы не удалите ничего лишнего. Комбинация с другими инструментами 1. Аудит прав доступа. Проверим файлы с неправильными правами доступа и исправим их:

find /path/to/dir -type f ! -perm 644 -exec chmod 644 {} \;
Теперь все файлы имеют права 644. 2. Поиск и отправка больших файлов. Найдём файлы больше 100 МБ и передадим список на удалённый сервер:

find /path/to/dir -size +100M -exec scp {} user@remote:/backup/ \;
3. Запрос на подтверждение действий. Используйте -ok вместо -exec для подтверждения действий:

find /path/to/dir -name "*.tmp" -ok rm {} \;
В данном случае каждое действие потребует подтверждения. BashTex 📱 #linux #utils

Интеллектуальные скрипты для анализа метрик и автоматической оптимизации системы Сегодня рассмотрим, как создать скрипты, которые анализируют метрики, принимают оптимизационные решения и используют элементы машинного обучения для управления резервными копиями. Сценарий автоматической оптимизации 1. Сбор метрик. Используем vmstat и iostat для системных метрик. Пример простого сбора метрик:

#!/bin/bash

cpu_load=$(vmstat 1 2 | tail -1 | awk '{print $13+$14}')
disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')

echo "CPU Load: $cpu_load%"
echo "Disk Usage: $disk_usage%"
2. Анализ метрик и автоматизация. Создадим скрипт, который проверяет загрузку системы и принимает меры: При высокой загрузке CPU - отправка уведомления. Если диск заполнен более чем на 80%, удаляются старые временные файлы.

#!/bin/bash

threshold_cpu=75
threshold_disk=80

cpu_load=$(vmstat 1 2 | tail -1 | awk '{print $13+$14}')
disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')

# Проверка загрузки CPU
if (( cpu_load > threshold_cpu )); then
  echo "High CPU load detected: ${cpu_load}%. Sending alert..."
  # Команда отправки уведомления (например, через Telegram API)
fi

# Проверка заполненности диска
if (( disk_usage > threshold_disk )); then
  echo "Disk usage critical: ${disk_usage}%. Cleaning up old files..."
  find /tmp -type f -mtime +7 -delete
fi
3. Управление резервными копиями с использованием ML. Обучение модели для предсказания времени пиков загрузки Для создания ML-модели используем Python. Можно использовать библиотеку scikit-learn для анализа временных рядов загрузки системы.

import pandas as pd
from sklearn.linear_model import LinearRegression

# Данные метрик (должны быть собраны заранее и сохранены)
data = pd.read_csv("system_metrics.csv")
X = data[['hour', 'day_of_week', 'cpu_load', 'disk_usage']]
y = data['backup_time']

# Обучение модели
model = LinearRegression()
model.fit(X, y)

# Прогноз времени для следующей резервной копии
new_metrics = [[14, 3, 45, 60]]  # Пример: текущий час, день недели, загрузка CPU и диска
predicted_backup_time = model.predict(new_metrics)
print(f"Рекомендуемое время для следующей резервной копии: {predicted_backup_time[0]} час")
Интеграция с Bash-скриптом Скрипт может запускать модель и адаптировать расписание резервного копирования:

#!/bin/bash

# Предсказание времени для резервной копии
backup_time=$(python3 predict_backup_time.py)

echo "Recommended backup time: $backup_time"

# Настройка cron на выполнение резервной копии
cron_job="0 $backup_time * * * /path/to/backup_script.sh"
(crontab -l ; echo "$cron_job") | crontab -
echo "Backup job scheduled at $backup_time:00"
BashTex 📱 #bash

Сразу видно, кто тут главный BashTex 📱 #юмор

Секреты использования tee Команда tee позволяет записывать вывод одновременно в файл и отображать его в терминале. Но её возможности гораздо шире, чем кажется на первый взгляд! 1. Добавление данных в файл. По умолчанию tee перезаписывает файл, но с опцией -a можно добавлять данные:

echo "Новая строка" | tee -a output.txt
Файл output.txt сохранит все предыдущие данные и добавит новую строку. 2. Дублирование вывода в несколько файлов. Вы можете одновременно записывать данные в несколько файлов:

echo "Логи обновлены" | tee log1.txt log2.txt log3.txt
Всё, что выведет команда, будет сохранено в трёх файлах одновременно. 3. Объединение с sudo. Иногда права доступа мешают записывать данные в файлы. Вот как решить это:

echo "Системная настройка" | sudo tee /etc/config.txt
Этот приём обходит ограничения записи без использования дополнительных редакторов. 4. Трансформация данных в реальном времени. tee можно использовать в пайплайнах для промежуточной проверки данных:

cat bigfile.txt | tee preview.txt | grep "важные данные" > result.txt
Здесь tee записывает содержимое файла в preview.txt, а затем передаёт его на обработку через grep. 5. Обработка stderr. По умолчанию tee работает только с stdout, но есть способ записывать и stderr:

{ ls non_existing_file 2>&1 1>&3 | tee errors.log; } 3>&1
Этот трюк записывает ошибки в файл errors.log и одновременно выводит их на экран. Полезные сценарии использования 1. Живой логинг: Сохраняйте данные и анализируйте их в реальном времени:

tail -f /var/log/syslog | tee live_log.txt
2. Одновременная передача данных в файл и на удалённый сервер:

some_command | tee local_log.txt | ssh user@server "cat > remote_log.txt"
3. Дублирование вывода сложных операций:

{ make build | tee build.log; } 2>&1 | grep "Error"
BashTex 📱 #linux #utils

Самовосстанавливающийся Bash-скрипт: проверка и запуск недостающих частей При создании сложных Bash-скриптов иногда требуется, чтобы они могли восстанавливать выполнение после прерываний. Это особенно актуально для долгих процессов, например, обработки файлов, миграции данных или массовой загрузки. В чем идея:
Сохранение состояния: фиксируем завершённые этапы в отдельном файле. Проверка состояния: перед выполнением этапа проверяем, был ли он выполнен ранее. Возобновление: пропускаем выполненные этапы, начиная с незавершённых.
Пример: обработка списка файлов. Допустим, у нас есть список файлов для обработки:

#!/bin/bash

# Список файлов для обработки
FILES=("file1.txt" "file2.txt" "file3.txt")

# Файл состояния
STATE_FILE="process.state"

# Функция для обновления состояния
update_state() {
  echo "$1" >> "$STATE_FILE"
}

# Создаём файл состояния, если его нет
if [[ ! -f "$STATE_FILE" ]]; then
  > "$STATE_FILE"
fi

# Загружаем выполненные этапы
COMPLETED=$(cat "$STATE_FILE")

echo "Начинаем обработку файлов..."

for FILE in "${FILES[@]}"; do
  # Проверяем, был ли файл уже обработан
  if echo "$COMPLETED" | grep -q "$FILE"; then
    echo "[Пропуск] $FILE уже обработан."
    continue
  fi

  # Обрабатываем файл
  echo "Обрабатываем $FILE..."
  sleep 2  # Имитация длительной работы

  # Если успешно, обновляем состояние
  update_state "$FILE"
  echo "[Готово] $FILE обработан."
done

echo "Все файлы обработаны!"
Вывод скрипта. Первый запуск:

Начинаем обработку файлов...
Обрабатываем file1.txt...
[Готово] file1.txt обработан.
Обрабатываем file2.txt...
[Готово] file2.txt обработан.
Обрабатываем file3.txt...
[Готово] file3.txt обработан.
Все файлы обработаны!
Повторный запуск:

Начинаем обработку файлов...
[Пропуск] file1.txt уже обработан.
[Пропуск] file2.txt уже обработан.
[Пропуск] file3.txt уже обработан.
Все файлы обработаны!
Где это может применимо:
Массовая обработка данных (например, логов). Резервное копирование с пропуском уже сохранённых файлов. Миграция больших объёмов данных. Загрузка или выгрузка информации с сетевых хранилищ.
BashTex 📱 #bash

Автоматическое восстановление после сбоев с использованием Bash-скриптов Быстрая реакция на системные сбои является ключом к минимизации времени простоя. Рассмотрим, как настроить автоматическое восстановление системы с помощью Bash-скриптов для замены поврежденных файлов и перезапуска критических служб. Для восстановления системы необходимо создать скрипт, который будет:
Проверять целостность ключевых файлов. Восстанавливать поврежденные файлы из резервной копии. Перезапускать критические службы.
Пример скрипта восстановления

#!/bin/bash

# Пути к резервным копиям и критическим файлам
BACKUP_DIR="/backup/system_files"
FILES_TO_CHECK=("/etc/nginx/nginx.conf" "/var/www/html/index.html")

# Проверка целостности файлов
for FILE in "${FILES_TO_CHECK[@]}"; do
    if [[ ! -f "$FILE" || ! cmp -s "$BACKUP_DIR/$(basename $FILE)" "$FILE" ]]; then
        echo "Файл $FILE поврежден или отсутствует. Восстанавливаем..."
        cp "$BACKUP_DIR/$(basename $FILE)" "$FILE"
    fi
done

# Перезапуск критических служб
SERVICES=("nginx" "mysql")
for SERVICE in "${SERVICES[@]}"; do
    if ! systemctl is-active --quiet "$SERVICE"; then
        echo "Служба $SERVICE не работает. Перезапускаем..."
        systemctl restart "$SERVICE"
    fi
done

echo "Восстановление завершено."
Автоматизация проверок с cron. Для регулярного выполнения скрипта можно использовать cron. Например, для запуска каждые 5 минут:

*/5 * * * * /path/to/restore_script.sh
BashTex 📱 #bash