BashTex | Linux
2.57K subscribers
48 photos
9 videos
291 links
Авторский канал для тех, кто хочет глубже погрузиться в мир Linux.

Подойдет для разработчиков, системных администраторов и DevOps

Реклама: @dad_admin
Download Telegram
Управление очередями фоновых задач в 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3
Динамическое распределение нагрузки между серверами на основе сетевого трафика

⚙️ Как это работает?

Балансировщики нагрузки анализируют входящий трафик, измеряют метрики серверов (задержки, использование ресурсов) и динамически перенаправляют запросы к менее загруженным узлам.

Основные механизмы:

Текущий сетевой трафик: оценивается объём данных, проходящих через сервер.
Задержка отклика: запросы направляются к серверу с минимальной задержкой.
Уровень нагрузки 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 https://backend;
}
}


Дополнительный модуль ngx_http_healthcheck_module позволяет учитывать время отклика серверов.

3. Traefik. Современное решение для балансировки в облачных и контейнерных средах. Traefik автоматически подхватывает информацию о серверах из Docker или Kubernetes.

BashTex 📱 #linux #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥2
Прерывание работы скрипта с сохранением прогресса

При выполнении долгих скриптов (например, обработки данных или резервного копирования) важно предусмотреть механизм безопасного прерывания с возможностью продолжения с того места, где процесс остановился. Сегодня про то, как можно организовать такую систему в 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2
Ну мы

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁26
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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19
Автономное восстановление сетевого соединения при сбоях

Что делать, если сервер внезапно теряет соединение? Вручную перезапускать сетевой интерфейс? Можно автоматизировать этот процесс.

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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥2🎅1
Динамическая замена строк в переменных без внешних утилит

В 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥2
Быстрая настройка 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Циклы с подсчётом времени выполнения: оптимизация итераций

При написании 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
This media is not supported in your browser
VIEW IN TELEGRAM
С планами на вечер определились ❤️

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁13👍4
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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Обработка многомерных массивов и ассоциативных списков в 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Проверка архивов на целостность: избегаем битых бэкапов

Создавать бэкапы - хорошая практика. Но что, если архив оказался битым в самый нужный момент? 😱 Разберемся, как проверять целостность архивов, чтобы не потерять важные данные.

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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Скрытая мощь { } и (( )) в Bash: работа с диапазонами и числами

В Bash есть два механизма - фигурные скобки { } для работы с диапазонами и двойные круглые скобки (( )) для арифметики. Как их использовать эффективно?

1️⃣ Диапазоны и генерация последовательностей с { }. Фигурные скобки позволяют быстро создавать списки значений.

ℹ️ Простая генерация чисел:


echo {1..5}

1 2 3 4 5


ℹ️ Шаг в последовательности:


echo {0..10..2}

0 2 4 6 8 10


ℹ️ Генерация букв:


echo {a..e}

a b c d e


ℹ️ Использование в for-циклах:


for i in {1..3}; do
echo "Файл_$i.txt"
done

Файл_1.txt
Файл_2.txt
Файл_3.txt


ℹ️ Создание файлов за раз:


touch file_{1..3}.txt


Создаст file_1.txt, file_2.txt, file_3.txt.

2️⃣ Арифметика с (( )) - быстрее и лаконичнее. (( )) используется для работы с числами без expr или let.

ℹ️ Базовые операции:


((sum = 5 + 3))
echo $sum

8


ℹ️ Инкремент и декремент:


x=10
((x++)) # Увеличить на 1
((x--)) # Уменьшить на 1
echo $x


ℹ️ Проверка условий без if:


x=5
(( x > 3 )) && echo "x больше 3"

x больше 3


ℹ️ Битовые операции:


((x = 5 & 3)) # Побитовое И
echo $x

1


3️⃣ Сочетание { } и (( ))

ℹ️ Сумма чисел от 1 до 10 с for:


sum=0
for i in {1..10}; do
((sum += i))
done
echo "Сумма: $sum"

Сумма: 55


ℹ️ Выбор только чётных чисел:


for i in {1..10}; do
((i % 2 == 0)) && echo "$i — чётное"
done


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍5
Please open Telegram to view this post
VIEW IN TELEGRAM
😁24👍4🔥2🫡1
Создание временных файлов и директорий

Временные файлы часто нужны в скриптах, но их создание вручную может привести к конфликтам имен или уязвимостям. mktemp решает эту проблему, создавая уникальные файлы и директории с безопасными правами доступа.

1️⃣ Создание временного файла


tmpfile=$(mktemp)
echo "Временный файл: $tmpfile"

Временный файл: /tmp/tmp.BX9G7f9a6Z


Файл создается с правами 600 (только владелец может читать и записывать).

2️⃣ Создание временного файла с заданным шаблоном


mktemp /tmp/mytemp.XXXXXX


XXXXXX заменяется случайными символами, исключая конфликты имен.

3️⃣ Создание временной директории


tmpdir=$(mktemp -d)
echo "Временная директория: $tmpdir"

Временная директория: /tmp/tmp.P8Z3K1qGfJ


⚠️ Удаление временных файлов:


rm -f "$tmpfile"
rm -rf "$tmpdir"


Или используем trap, чтобы удалить временные файлы при завершении скрипта:


trap 'rm -f "$tmpfile"' EXIT


BashTex 📱 #linux #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16
mtr vs traceroute: анализ сетевых маршрутов

Когда нужно диагностировать сетевые проблемы, чаще всего используют traceroute или mtr. Оба инструмента помогают определить путь пакетов до целевого хоста, но mtr значительно превосходит traceroute по функциональности. Разберем различия.

▪️traceroute - классический анализ маршрута

traceroute показывает последовательность узлов, через которые проходит пакет до цели.


traceroute bashtex.com

1 192.168.1.1 (192.168.1.1) 1.234 ms 1.567 ms 1.678 ms
2 10.0.0.1 (10.0.0.1) 2.345 ms 2.678 ms 2.789 ms
3 203.0.113.1 (203.0.113.1) 10.345 ms 11.456 ms 12.567 ms


📌 Показывает только один запуск, без динамики.

▪️ mtr - интерактивный анализ сети

mtr комбинирует traceroute и ping, предоставляя динамическое обновление маршрута.


mtr bashtex.com

HOST: myhost Loss% Snt Last Avg Best Wrst StDev
1.|-- 192.168.1.1 0.0% 10 1.2 1.3 1.0 1.5 0.2
2.|-- 10.0.0.1 0.0% 10 2.4 2.5 2.2 3.0 0.3
3.|-- 203.0.113.1 10.0% 10 10.4 11.2 10.0 13.5 1.2


📌Отличия от traceroute:

Постоянно обновляет данные (динамический анализ).
Показывает потерю пакетов (Loss%), среднее и максимальное время отклика (Avg, Wrst).
Удобно для выявления нестабильных узлов.

💡 Когда использовать?

traceroute - если нужен единоразовый снимок маршрута.
mtr - если важно видеть динамику и выявить нестабильные узлы.

BashTex 📱 #linux #networks
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Никаких Windows в этом доме!

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁19🫡7👍1🔥1
Масштабируемое развертывание приложений с Bash и Docker

😎 Основная идея:

Проверять текущую загрузку CPU/памяти
Автоматически запускать дополнительные контейнеры при высокой нагрузке
Останавливать лишние контейнеры при снижении нагрузки

▪️ Bash-скрипт для масштабирования


#!/bin/bash

APP_NAME="myapp"
IMAGE="myapp_image"
LIMIT=70 # Порог загрузки CPU в процентах
MAX_CONTAINERS=5

# Получаем текущую загрузку CPU
CPU_LOAD=$(awk '{print $1}' <(grep 'cpu ' /proc/stat | awk '{print ($2+$4)*100/($2+$4+$5)}'))

# Получаем текущее количество запущенных контейнеров
RUNNING_CONTAINERS=$(docker ps -q -f "name=$APP_NAME" | wc -l)

if (( $(echo "$CPU_LOAD > $LIMIT" | bc -l) )); then
if (( RUNNING_CONTAINERS < MAX_CONTAINERS )); then
echo "Высокая нагрузка ($CPU_LOAD%). Запускаем новый контейнер..."
docker run -d --name "$APP_NAME-$RUNNING_CONTAINERS" $IMAGE
else
echo "Достигнут лимит контейнеров ($MAX_CONTAINERS)."
fi
else
if (( RUNNING_CONTAINERS > 1 )); then
STOP_CONTAINER=$(docker ps -q -f "name=$APP_NAME" | tail -n 1)
echo "Нагрузка низкая ($CPU_LOAD%). Останавливаем контейнер $STOP_CONTAINER..."
docker stop $STOP_CONTAINER && docker rm $STOP_CONTAINER
fi
fi


⚙️ Как использовать?

1. Сохраните скрипт, например, как autoscale.sh
2. Сделайте его исполняемым:


chmod +x autoscale.sh


3. Настройте запуск через cron (например, каждые 5 минут):


crontab -e


Добавьте строку:


*/5 * * * * /path/to/autoscale.sh >> /var/log/autoscale.log 2>&1


🏳️ Что получаем:

При нагрузке выше 70% добавляются контейнеры
При снижении нагрузки контейнеры удаляются
Управление происходит автоматически

BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🫡1
Автоматическое монтирование сетевых папок при загрузке системы

Если вам нужно подключать сетевые папки автоматически при старте системы, лучше всего использовать /etc/fstab или systemd automount. Разберем оба способа.

1️⃣ Использование /etc/fstab. Добавьте строку в /etc/fstab, чтобы система монтировала папку при загрузке:


//192.168.1.100/share /mnt/share cifs username=user,password=pass,iocharset=utf8,_netdev 0 0


//192.168.1.100/share - путь к папке на сервере
/mnt/share - локальная точка монтирования
cifs - используемый протокол (для Windows/Samba)
_netdev - монтирование после установки сети


⚠️ После изменения /etc/fstab примените команду:


mount -a


2️⃣ Автоматическое монтирование через systemd. Создайте юнит /etc/systemd/system/mnt-share.mount:


[Unit]
Description=Автоматическое монтирование сетевой папки
After=network-online.target

[Mount]
What=//192.168.1.100/share
Where=/mnt/share
Type=cifs
Options=username=user,password=pass,iocharset=utf8

[Install]
WantedBy=multi-user.target


Затем включите монтирование:


systemctl daemon-reload
systemctl enable --now mnt-share.mount


💡 Какой способ выбрать?

fstab - если подключение постоянно и предсказуемо
systemd - если нужна гибкость и управление через systemctl

BashTex 📱 #linux #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥1