es
Feedback
BashTex | Linux

BashTex | Linux

Ir al canal en Telegram

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

Mostrar más
2 524
Suscriptores
-224 horas
-67 días
Sin datos30 días
Archivo de publicaciones
Авторазрешение зависимостей скрипта через dynamic sourcing В больших bash-проектах часто есть несколько вспомогательных файлов (.sh или .bash), которые содержат функции и настройки. Проблема в том, что: 📍Скрипт может запуститься в другом каталоге - пути сломаются 📍Некоторые модули могут отсутствовать или лежать в нестандартных местах 📍При изменении структуры проекта придётся вручную переписывать source Решение: динамическое подключение модулей 1️⃣ Автоматический source по списку зависимостей

#!/bin/bash
set -e

# Список модулей, которые нужны для работы
modules=("logger.sh" "utils.sh" "net.sh")

# Каталоги для поиска
search_paths=(
  "$PWD/lib"
  "$PWD/modules"
  "/usr/local/share/myscript"
)

for mod in "${modules[@]}"; do
    found=0
    for path in "${search_paths[@]}"; do
        if [[ -f "$path/$mod" ]]; then
            source "$path/$mod"
            echo "[OK] Loaded $mod from $path"
            found=1
            break
        fi
    done
    if (( !found )); then
        echo "[ERROR] Module $mod not found" >&2
        exit 1
    fi
done
Такой подход позволяет легко добавлять новые пути в поиск - модуль подтянется сам. 2️⃣ Dynamic sourcing по зависимостям из конфигурации. Можно вынести список зависимостей в отдельный файл deps.txt:

logger.sh
utils.sh
net.sh
А в скрипте:

while IFS= read -r dep; do
    found=0
    for path in "${search_paths[@]}"; do
        if [[ -f "$path/$dep" ]]; then
            source "$path/$dep"
            found=1
            break
        fi
    done
    (( found )) || { echo "[MISSING] $dep" >&2; exit 1; }
done < deps.txt
3️⃣ Поиск относительно текущего скрипта. Чтобы скрипт работал из любого места:

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/logger.sh"
▪️ Плюсы подхода: ✅Нет жестких путей; ✅Можно запускать в разных окружениях; ✅Удобно для open-source проектов и shared-библиотек; ✅Легко расширять - просто добавь файл в deps.txt. BashTex 📱 #bash

😎 BashTex 📱 #юмор
😎 BashTex 📱 #юмор

Печать таблиц с автошириной и выравниванием column, awk, printf - минимализм, читаемость и стиль без excel и pandas. Bash-скрипты часто выводят списки, но без форматирования:

echo "user1 1234 active"
echo "user10 99 disabled"
Вывод «прыгает» - неудобно читать. Решаем с помощью: column - автоширина и выравнивание awk - гибкая фильтрация и формат printf - точный контроль длины столбцов ▪️ Быстрое решение: column -t

#!/bin/bash

echo -e "USER ID STATUS\nuser1 1234 active\nuser10 99 disabled" | column -t
Результат:

USER    ID   STATUS
user1   1234 active
user10  99   disabled
-t = "табличный режим", разбивает по пробелам, автоширина. ▪️ Альтернатива: awk с выравниванием

awk '{ printf "%-10s %-6s %-10s\n", $1, $2, $3 }' <<< "user1 1234 active
user10 99 disabled"
Результат:

user1     1234   active    
user10    99     disabled 
Плюсы: Точное выравнивание; Подходит для чисел, выравненных по правому краю (%6s, %6d). ▪️ Автоматизация с массивом и printf

header=("USER" "ID" "STATUS")
rows=(
  "user1 1234 active"
  "user10 99 disabled"
  "admin 5678 maintenance"
)

{
  printf "%-10s %-6s %-12s\n" "${header[@]}"
  for row in "${rows[@]}"; do
    printf "%-10s %-6s %-12s\n" $row
  done
} | column -t
▪️ Таблица из файла CSV

column -s, -t < users.csv
-s, - задает разделитель (запятая), -t - табличный вид. BashTex 📱 #bash

Планировщик задач с временными окнами: только ночью, только по будням, только в выходные Иногда cron не подходит: 📍 нужно запустить задачу в определенное время суток, 📍 но не строго по расписанию, а если есть что обрабатывать, 📍 и не запускать ее днем, когда сервер под нагрузкой. Тут пригодится встроенная проверка временных окон в скрипте, а cron пусть просто каждые 10 минут запускает "умный планировщик". 🛠 Пример: выполнение задачи только с 02:00 до 05:00 по будням

#!/bin/bash

#настройки временного окна
start_hour=2
end_hour=5

# день недели (1..5 = пн-пт)
dow=$(date +%u)

#часы сейчас
hour=$(date +%H)

#проверка: будний день и нужное время
if (( dow >= 1 && dow <= 5 )) && (( hour >= start_hour && hour < end_hour )); then
  echo "[$(date)] Временное окно открыто. Выполняем задачу."
  
  #здесь реальная задача:
  /opt/backup/backup-db.sh

else
  echo "[$(date)] Вне временного окна. Пропуск."
fi
▪️ Расширение: исключение праздников (по файлу)

holiday_file="/etc/holidays.txt"
today=$(date +%Y-%m-%d)

if grep -q "$today" "$holiday_file"; then
  echo "Сегодня праздник. Задача не выполняется."
  exit 0
fi
▪️ Альтернатива: запуск только по выходным с 3 до 6 утра

(( dow == 6 || dow == 7 )) && (( hour >= 3 && hour < 6 )) && run_task
▪️ Запуск через cron

*/10 * * * * /usr/local/bin/task_scheduler.sh >> /var/log/task.log 2>&1
BashTex 📱 #bash #utils

Упаковка структуры каталогов с фильтрацией Когда нужно архивировать не весь каталог, а только часть - с фильтрацией и даже переименованием путей внутри архива - на помощь приходят find, tar и его флаг --transform. ▪️ Базовый пример: фильтруем по маске и архивируем

find project/ -type f -name "*.conf" > list.txt
tar -czf config_backup.tar.gz -T list.txt
Тут мы архивируем только .conf-файлы. ▪️ Добавим переименование путей внутри архива. Архивируем все из src/, но хотим, чтобы внутри архива это лежало как app/.

tar -czf app.tar.gz \
  --transform='s|^src|app|' \
  -C ./ src
--transform использует sed-подобные выражения. Тут s|^src|app| означает: заменить в начале пути src на app. ▪️ Упаковка через find + --transform + относительные пути. Предположим, хотим архивировать только .sh и .py-файлы, заменив scripts/ на bin/ внутри архива:

find scripts/ -type f \( -name "*.sh" -o -name "*.py" \) > filelist.txt

tar -czf bin_scripts.tar.gz \
  --transform='s|^scripts|bin|' \
  -T filelist.txt
▪️ Упрощенный однострочник:

find scripts/ -type f -name "*.sh" \
| tar -czf archive.tar.gz --transform='s|^scripts|bin|' -T -
▪️ Продвинутый пример: исключения + трансформация + директория

find ./src -type f ! -name "*.tmp" \
| tar -czf src_clean.tar.gz \
    --transform='s|^./src|clean_src|' \
    -T -
BashTex 📱 #bash #utils

Использование readarray и mapfile для групповой обработки строк Когда обрабатываем многострочный вывод - часто используем while read, но есть более быстрый способ: mapfile (синоним - readarray). ❓ Что делает mapfile? Читает строки из stdin или команды сразу в массив, построчно:

mapfile -t lines < input.txt
# теперь ${lines[0]}, ${lines[1]} и т.д. - отдельные строки
Аналог:

readarray -t lines < input.txt
Флаг -t удаляет \n на конце строк. ▪️ Обработка вывода команд:

mapfile -t users < <(cut -d: -f1 /etc/passwd)

for user in "${users[@]}"; do
  echo "Пользователь: $user"
done
▪️ Фильтрация и трансформация. Комбинируем с grep, awk, sort, uniq:

mapfile -t services < <(systemctl list-units --type=service | awk '/running/ {print $1}')

for svc in "${services[@]}"; do
  echo "Активный сервис: $svc"
done
▪️ Срезы и подмассивы. Работа с частями:

mapfile -t logs < <(tail -n 100 /var/log/syslog)

# последние 5 строк
printf '%s\n' "${logs[@]: -5}"
▪️ Использование с read-only входом:

some_func() {
  local lines=()
  mapfile -t lines
  echo "Прочитано строк: ${#lines[@]}"
}

cat /etc/passwd | some_func
BashTex 📱 #bash #utils

Наткнулся на канал Вячеслава Федосеева — тимлид девопс в «Честном знаке». Делится опытом (ещё с нулевых-десятых админит), вед
+3
Наткнулся на канал Вячеслава Федосеева — тимлид девопс в «Честном знаке». Делится опытом (ещё с нулевых-десятых админит), ведёт стримы в канале, разбирает резюме и собесы, много про карьеру. Покопался кто он: выступает на DevOps Conf, ведёт проекты (нашел, что зимой делал подкасты с бигтехами про их требования к девопсами — много любопытного) Короче, живой блог про девопс и карьеру без воды и с высоты своего опыта 👍 Подписывайтесь, чтобы не потерять: DevOps Bootcamp с Федосеевым 📌

Автоматическая отправка отчета об активности crontab-скриптов Когда скрипты запускаются по cron, часто мы не знаем - сработали ли они, что вывели, были ли ошибки. В результате важная задача могла "молча" упасть, и никто не заметил. Решение - генерация и отправка ежедневного отчета о выполнении всех cron-задач с логами. ⭐️ Принцип: 📍 Все cron-скрипты логируют вывод в файл. 📍 В конце дня другой скрипт собирает и отправляет логи (по почте, в телегу, в файл). 📍 Старая логика - архивируется или удаляется. 🛠 Пример скрипта: /usr/local/bin/cron-report.sh

#!/bin/bash

LOGDIR="/var/log/cron-jobs"
REPORT="/tmp/cron_report_$(date +%F).log"

echo "Отчет о задачах cron за $(date)" > "$REPORT"
echo "===============================" >> "$REPORT"

for logfile in "$LOGDIR"/*.log; do
  echo -e "\n[$(basename "$logfile")]" >> "$REPORT"
  tail -n 50 "$logfile" >> "$REPORT"
done

#Отправить отчет (почта или телега)
mail -s "Cron Report $(hostname)" admin@bashtex.com < "$REPORT"

#Удаление старых логов старше 7 дней
find "$LOGDIR" -name '*.log' -mtime +7 -delete
▪️ Пример cron-задания для скрипта:

0 23 * * * /usr/local/bin/cron-report.sh
▪️ Пример логирования в других скриптах. В каждом cron-скрипте указываем:

#!/bin/bash
# example_job.sh

LOG="/var/log/cron-jobs/example_job.log"

echo "==== $(date) ====" >> "$LOG"
your_command_here >> "$LOG" 2>&1
✅ Права доступа к логам ограничены: chmod 640, владелец - root или нужный юзер. ✅Логи очищаются через find или logrotate. BashTex 📱 #bash

Распараллеливание задач с контролем количества потоков Когда нужно запустить 1000 задач, но не обрушить сервер - важно уметь распараллеливать выполнение с ограничением на количество одновременных процессов. В bash это можно реализовать без внешних утилит вроде parallel. 🌟 Задача: скачать список URL-ов, но не больше N одновременно. 🛠 Пример скрипта:

#!/bin/bash

MAX_JOBS=5
URLS_FILE="urls.txt"

semaphore() {
  while (( $(jobs -rp | wc -l) >= MAX_JOBS )); do
    sleep 0.5
  done
}

process_url() {
  local url="$1"
  echo "[*] Загрузка $url"
  curl -s -o /dev/null "$url" && echo "[+] $url OK" || echo "[-] $url FAIL"
}

while read -r url; do
  semaphore
  process_url "$url" &
done < "$URLS_FILE"

wait
echo "Все задачи завершены"
▪️ Пояснения: jobs -rp - выводит только PID активных фоновых задач. semaphore() - блокирует запуск, если уже выполняется $MAX_JOBS процессов. wait в конце - ждет завершения всех фоновых заданий. ▪️ Когда использовать: 📍Массовая обработка файлов (сжатие, конвертация). 📍Сканирование сети. 📍Пакетные вычисления или API-запросы. BashTex 📱 #bash

Bash-модули: подключение и структура библиотек функций Когда проект разрастается, скрипты превращаются в мешанину повторяющегося кода. Решение - выносить логику в отдельные .sh-файлы и подключать их как модули. Bash позволяет это делать просто и удобно с помощью source. ▪️ Пример структуры проекта:

project/
├── main.sh
├── lib/
│   ├── colors.sh
│   ├── network.sh
│   └── disk.sh
▪️ Как подключать:

#!/bin/bash
# main.sh

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/colors.sh"
source "$SCRIPT_DIR/lib/network.sh"
source "$SCRIPT_DIR/lib/disk.sh"

log_info "Начинаем выполнение..."
check_network
check_disk_usage
▪️ Файл colors.sh:

#!/bin/bash

RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'

log_info() {
  echo -e "${GREEN}[INFO]${NC} $*"
}

log_error() {
  echo -e "${RED}[ERROR]${NC} $*"
}
▪️ Файл network.sh:

#!/bin/bash

check_network() {
  if ! ping -c1 8.8.8.8 &>/dev/null; then
    log_error "Нет подключения к интернету"
  else
    log_info "Сеть доступна"
  fi
}
▪️ Файл disk.sh:

#!/bin/bash

check_disk_usage() {
  local usage
  usage=$(df / | awk 'NR==2 {print $5}')
  log_info "Использование диска: $usage"
}
⭐️ Рекомендации:
📍 Используй SCRIPT_DIR для относительных путей (надежно даже из cron); 📍 Разделяй модули по темам (log.sh, fs.sh, sys.sh и т.д.); 📍 Добавляй set -euo pipefail в main.sh, но не обязательно в модулях - иначе они могут прерывать подключение.
BashTex 📱 #bash

Решать RnD-задачи интересно, но ещё интереснее получать за это классные бонусы! Всероссийский чемпионат по искусственному инт
Решать RnD-задачи интересно, но ещё интереснее получать за это классные бонусы! Всероссийский чемпионат по искусственному интеллекту RuCode — это возможности: ✍️ Добавить крутой кейс в портфолио ✍️ Посоревноваться с коллегами и повысить свою квалификацию ✍️ Выиграть призы: игровую приставку Nintendo Switch 2, умную колонку SberBoom, фирменный мерч ✍️ Получить сертификат о ДПО МФТИ Задачи, предоставленные компаниями — партнёрами чемпионата, уже опубликованы!
У специалистов, преподавателей, студентов и школьников будет шанс посостязаться в решении практических задач с использованием методов машинного обучения и анализа данных до 26 октября.
А 13 ноября состоится награждение в Москве, где отметят лучших из лучших 👏 Регистрируйтесь на RuCode, чтобы влиться в большое ИТ-сообщество уже сейчас! Реклама

Оптимизация вложенных циклов и массивов Вложенные циклы в bash - частая причина медленных скриптов при работе с большими массивами и файлами. Особенно если ты обрабатываешь 10000+ элементов и каждый проход делает grep, awk, cut, cat, sed... ▪️ Антипаттерн

for i in "${list1[@]}"; do
  for j in "${list2[@]}"; do
    if [[ "$i" == "$j" ]]; then
      echo "Match: $i"
    fi
  done
done
➖ Это O(N²). Если массивы по 10к строк - будет 100 млн сравнений. ▪️ Оптимизация через associative array (Bash 4+)

declare -A lookup

# Заполняем хеш
for item in "${list2[@]}"; do
  lookup["$item"]=1
done

# Ищем быстро
for i in "${list1[@]}"; do
  if [[ ${lookup["$i"]+found} ]]; then
    echo "Match: $i"
  fi
done
➕ Это уже O(N). И в 1000 раз быстрее. ▪️ Ускорение чтения данных. Избавляемся от cat в цикле: ➖ Плохо:

while read line; do
  cat "$line"
done < files.txt
➕ Лучше:

mapfile -t files < files.txt

for f in "${files[@]}"; do
  cat "$f"
done
▪️ Убираем лишние циклы. Когда можно - переноси логику внутрь awk, grep, join, sort -m и т.д. Пример: пересечение двух файлов без bash-циклов:

sort file1.txt file2.txt | uniq -d
BashTex 📱 #bash #utils

Бесплатный урок по Apache Kafka⭐️ Учим работать с реальными исходными данными, а не на теоретических примерах. ✅Расскажем про
Бесплатный урок по Apache Kafka⭐️ Учим работать с реальными исходными данными, а не на теоретических примерах. ✅Расскажем про язык Кафки: топики, партиции, продюсеры-консьюмеры, кластер, ноды.  ✅Рассмотрим: как работают очереди сообщений, сколько должно быть консьюмеров для эффективной вычитки, как повысить надёжность кластера с помощью репликации данных. ✅Покажем, как развернуть кластер Кафки на своём ПК с 3 нодами, schema-registry и авторизацией. Обычно в инструкциях кластер из 1 ноды, зукипера и 1 брокера, но это не наш путь, смотрим сразу на практике. Забрать урок👉🏻в боте

Построение интерактивного CLI-меню с автодополнением и подсказками Хотите, чтобы ваши скрипты ощущались как полноценные CLI-утилиты? Добавим в них: интерактивное меню, автодополнение (TAB) и встроенные описания/подсказки по командам. Создадим скрипт с поддержкой команд (подкоманд) и аргументов, а затем подключаем к нему bash completion через complete -F. ▪️ Пример CLI с командами и подсказками

#!/usr/bin/env bash

# --- CLI-команды ---
main() {
  local cmd="$1"; shift
  case "$cmd" in
    start) echo "Запуск сервиса" ;;
    stop)  echo "Остановка сервиса" ;;
    status) echo "Статус сервиса" ;;
    help|"") show_help ;;
    *) echo "Неизвестная команда: $cmd"; show_help ;;
  esac
}

# --- Подсказки ---
show_help() {
  cat <<EOF
Доступные команды:
  start    - Запустить сервис
  stop     - Остановить сервис
  status   - Показать статус
  help     - Показать справку
EOF
}

main "$@"
▪️ Автодополнение через complete -F. Создаем функцию для автодополнения:

_cli_autocomplete() {
  local cur prev opts
  COMPREPLY=()
  cur="${COMP_WORDS[COMP_CWORD]}"
  opts="start stop status help"

  COMPREPLY=( $(compgen -W "${opts}" -- "$cur") )
  return 0
}

# Подключаем к нашему скрипту
complete -F _cli_autocomplete mycli
Положите этот код в .bashrc или .bash_completion.d/mycli, и автодополнение команд заработает:

$ ./mycli <TAB>
start   status   stop   help
▪️ Описание команд при наведении. Если используете bash-completion, можно интегрировать подсказки в стиле:

complete -o nospace -o default -F _cli_autocomplete mycli
В более продвинутых реализациях можно добавить справку по каждой команде - через compopt, __ltrim_colon_completions, compgen и массив COMPREPLY. ▪️ Рекомендованная структура CLI

mycli
├── bin/
│   ├── start
│   ├── stop
│   ├── status
└── mycli
Такой подход с автозагрузкой команд из bin/ позволяет расширять CLI без изменения основного скрипта. BashTex 📱 #bash #utils

Как красиво ждать с прогрессом в терминале Иногда скрипту нужно подождать: пауза перед перезапуском сервиса, таймер перед завершением работы, задержка в цикле. Просто sleep - бывает скучно. Сделаем задержку с индикатором прогресса прямо в терминале. ▪️ Вариант 1: простой таймер с индикатором прогресса

wait_with_progress() {
  local seconds=$1
  echo -n "Ожидание $seconds сек: ["
  for ((i = 0; i < seconds; i++)); do
    echo -n "#"
    sleep 1
  done
  echo "] Готово!"
}

wait_with_progress 5
Вывод:

Ожидание 5 сек: [#####] Готово!
▪️ Вариант 2: "бегающий" индикатор во время ожидания

spinner_wait() {
  local pid=$!
  local delay=0.1
  local spinstr='|/-\'
  echo -n "Ждем... "
  while kill -0 $pid 2>/dev/null; do
    local temp=${spinstr#?}
    printf " [%c]  " "$spinstr"
    spinstr=$temp${spinstr%"$temp"}
    sleep $delay
    printf "\b\b\b\b\b\b"
  done
  echo "Готово!"
}

# Пример: запуск команды с ожиданием
(sleep 5) & spinner_wait
Этот индикатор крутится, пока выполняется команда. ▪️ Вариант 3: таймер обратного отсчета

countdown() {
  local sec=$1
  while [ $sec -gt 0 ]; do
    printf "\rОсталось: %2d сек..." "$sec"
    sleep 1
    ((sec--))
  done
  echo -e "\rВремя вышло!        "
}

countdown 10
Это удобно для сценариев с обратным отсчетом до перезапуска или отката. ⭐️ Также можно использовать tput civis и tput cnorm для скрытия/показа курсора:

tput civis  # скрыть
# ...индикатор...
tput cnorm  # вернуть
BashTex 📱 #bash

😎 Щас все сделаю как надо BashTex 📱 #юмор
😎 Щас все сделаю как надо BashTex 📱 #юмор

Отправка файлов на удаленный сервер с логированием и проверкой контрольных сумм Как надежно передавать файлы на сервер: с логом, контрольной суммой и валидацией? Передача файлов - обычная задача, но часто делается без верификации. Добавим автоматический контроль: ▪️ Инструменты
scp / rsync - передача sha256sum - хеши ssh - удаленное выполнение logger / лог-файл - аудит
▪️ Пример: передача и проверка файла

#!/bin/bash

SRC_FILE="/data/backup.tar.gz"
DEST_USER="user"
DEST_HOST="backup.server"
DEST_PATH="/srv/backups/"
LOG="/var/log/file_transfer.log"

FILENAME=$(basename "$SRC_FILE")
CHECKSUM=$(sha256sum "$SRC_FILE" | awk '{print $1}')
STAMP=$(date '+%F %T')

echo "$STAMP : Начата передача $FILENAME" | tee -a "$LOG"

# Отправка файла
scp "$SRC_FILE" "$DEST_USER@$DEST_HOST:$DEST_PATH"

# Проверка хеша на удаленной стороне
REMOTE_SUM=$(ssh "$DEST_USER@$DEST_HOST" "sha256sum '$DEST_PATH/$FILENAME' | awk '{print \$1}'")

# Сравнение и лог
if [[ "$REMOTE_SUM" == "$CHECKSUM" ]]; then
  echo "$STAMP : Успешно: $FILENAME передан и проверен" | tee -a "$LOG"
else
  echo "$STAMP : Ошибка: контрольные суммы не совпадают!" | tee -a "$LOG"
fi
BashTex 📱 #bash

Работа с датами и интервалами времени без внешних утилит Как работать с датами и временем, если нельзя использовать date, awk, python, jq и т.п. - только встроенные средства? Такое бывает в ограниченных окружениях (initrd, контейнеры, busybox). Что остается? Только POSIX-переменные, арифметика и системный вызов времени через /proc. ▪️ Получение текущего времени в секундах (POSIX timestamp)

now=$(</proc/uptime)              # uptime в секундах с долей
timestamp=$(cut -d. -f1 <<< "$now")  # отбрасываем дробную часть
echo "Uptime (сек): $timestamp"
Но если доступен Bash ≥ 4.2, можно так:

now=$(printf '%(%s)T\n' -1)  # текущий timestamp
▪️ Расчет интервала (например, сколько секунд назад)

start=1721133000
now=$(printf '%(%s)T\n' -1)
delta=$((now - start))
echo "Прошло $delta секунд"
▪️ Преобразование секунд в формат ЧЧ:ММ:СС

secs=9384  # Пример: 2 ч, 36 мин, 24 сек

printf -v hh '%02d' $((secs / 3600))
printf -v mm '%02d' $(((secs % 3600) / 60))
printf -v ss '%02d' $((secs % 60))

echo "$hh:$mm:$ss"
▪️ Проверка "дата в будущем/прошлом"

deadline=1721190000
now=$(printf '%(%s)T\n' -1)

if (( now > deadline )); then
  echo "Просрочено"
else
  echo "Еще в сроке"
fi
▪️ Простая "через N секунд"

wait_for=$((60 * 5))  # 5 минут
start=$(printf '%(%s)T\n' -1)

while true; do
  now=$(printf '%(%s)T\n' -1)
  (( now - start >= wait_for )) && break
  sleep 1
done

echo "Прошло 5 минут"
▪️ Мини-фреймворк времени без date. Если date нет вообще, можно использовать /proc/uptime как источник времени с начала загрузки. Это полезно в init-сценариях и embedded-системах.

get_now() {
  cut -d. -f1 /proc/uptime
}
Даже без date, python и awk можно: считать интервалы, вычислять прошедшее время, форматировать в ЧЧ:ММ:СС, сравнивать сроки и "таймерить". Это помогает писать portable-скрипты под ограниченные окружения. BashTex 📱 #bash

Генерация временных учёток с автоудалением Временные учетки в linux с автозапретом - удобный способ: 📍 выдать доступ коллеге или заказчику на пару часов; 📍 дать временный SSH-доступ без ручной чистки; 📍 создать пользователя на ограниченное время (в минутах/часах). ▪️ Пример: учетка на 1 час

USER="tempuser"
PASS="$(openssl rand -base64 12)"
TIMEOUT_MIN=60

# Создание пользователя
useradd -m "$USER"
echo "$USER:$PASS" | chpasswd
echo "Учетка $USER создана. Пароль: $PASS"

# Блокировка через timeout
echo "passwd -l $USER && echo '[INFO] $USER заблокирован'" | at now + "$TIMEOUT_MIN" minutes
▪️ Альтернатива: удаление полностью. Если нужно удалить пользователя, а не только заблокировать:

echo "pkill -u $USER; userdel -r $USER" | at now + "$TIMEOUT_MIN" minutes
▪️ Дополнительно: запрет sudo и ограничение SSH Не добавляйте пользователя в группы типа sudo. Можно ограничить доступ в sshd_config:

Match User tempuser
    ForceCommand echo "Временный доступ завершен"
    AllowTcpForwarding no
    X11Forwarding no
▪️ Оборачивание в скрипт

#!/bin/bash
USER="temp$RANDOM"
PASS="$(openssl rand -base64 10)"
TIMEOUT_MIN=30

useradd -m "$USER"
echo "$USER:$PASS" | chpasswd
echo "Пользователь $USER создан на $TIMEOUT_MIN минут"
echo "Логин: $USER"
echo "Пароль: $PASS"

echo "userdel -r $USER" | at now + "$TIMEOUT_MIN" minutes
BashTex 📱 #bash #security

Реализация цикла с таймаутом ожидания результата и отменой Polling с таймаутом в bash - когда нужно подождать результат, но не вечно. Идеально подходит для: 📍 Ожидания ответа от API; 📍 Проверки, появился ли файл; 📍 Проверки, поднялся ли сервис; 📍 Паузы перед перезапуском, если условие не выполнено. 1️⃣ Пример: ждать файл не больше 10 секунд

TIMEOUT=10
INTERVAL=1
FILE="/tmp/ready.flag"

for ((i=0; i<TIMEOUT; i+=INTERVAL)); do
    if [[ -f "$FILE" ]]; then
        echo "Файл найден"
        break
    fi
    sleep "$INTERVAL"
done

if [[ ! -f "$FILE" ]]; then
    echo "Таймаут: файл не появился"
fi
2️⃣ Пример: проверка доступности порта (через nc)

HOST="localhost"
PORT=8080
TIMEOUT=15

for ((i=0; i<TIMEOUT; i++)); do
    if nc -z "$HOST" "$PORT"; then
        echo "Сервис доступен"
        break
    fi
    sleep 1
done

if ! nc -z "$HOST" "$PORT"; then
    echo "Сервис не запустился за $TIMEOUT секунд"
fi
3️⃣ Более обобщенная функция

poll_until() {
    local timeout=$1
    local interval=$2
    shift 2
    local elapsed=0

    while ((elapsed < timeout)); do
        if "$@"; then
            return 0
        fi
        sleep "$interval"
        ((elapsed+=interval))
    done
    return 1
}
▪️Использование:

poll_until 10 1 curl -sf http://localhost:8080/health || echo "Недоступен"
Polling pattern с ограничением по времени - инструмент, когда “ожидание результата” должно быть контролируемым. BashTex 📱 #bash #utils