У нас, в компании СТАРКОВ Групп Bash-скрипты — это не просто инструмент, а часть нашей ежедневной практики. Когда десятки серверов требуют внимания, а задачи повторяются изо дня в день, ручное выполнение команд становится неэффективным.
А ведь большинство рутинных задач и операций можно автоматизировать.
Bash-скрипты представляют собой мощный инструмент для автоматизации задач, особенно в Unix-подобных операционных системах, таких как Linux и macOS. Они помогают автоматизировать рутинные задачи, обеспечивая более быструю и эффективную работу в системе.
Bash (Bourne Again Shell) — это интерпретируемый язык командной строки, используемый для выполнения команд и написания скриптов.
Bash-скрипты могут выполнять такие задачи, как копирование файлов, обработка текста, управление системными ресурсами, запуск программ и многое другое.
Итак, создать bash-скрипт очень просто:
- Откройте терминал и создайте файл:
touch myscript.sh
или сразу в редакторе (vim, nano, gedit):
nano myscript.sh
- В начале содержимого файла добавьте шебанг, чтобы указать, что это bash-скрипт:
#!/bin/bash
- Создайте скрипт, либо скопируйте его;
- Сделайте файл исполняемым:
chmod +x myscript.sh
- Проверьте скрипт на ошибки синтаксиса командой:
bash -n ./myscript.sh
А также на ошибки вида "Literal carriage return", например, с помощью vim:
vim -b myscript.sh
При использовании команд из под root будьте осторожны, дабы не навредить системе. В принципе информации в интернете полно, можно ознакомиться хотя бы с базовыми вещами, для понимания: здесь и здесь2.
Применительно к системам, где установлен DirectumRX на Linux и его компоненты, можно выделить следующие аспекты применения автоматизации на основе скриптов Bash и различных команд:
Итак, поехали!
Под ротацией логов вообще подразумевается: чистка лишних и устаревших логов DirectumRX, логов и системных журналов ОС, логов БД, логов сопутствующих программ и сервисов, как по размеру, так и по дате, для поддержания системы в чистоте и порядке.
В ОС Linux можно автоматизировать очистку логов с помощью bash-скриптов, и по расписанию.
a) Логи системы подчищаем с помощью встроенной утилиты Logrotate:
пример файла настройки /etc/logrotate.d/postgresql-common для ротации логов postgresql:
/var/log/postgresql/*.log {
daily
rotate 7
size=100M
copytruncate
delaycompress
compress
notifempty
missingok
su root root
}
Эта конфигурация указывает, что logrotate будет ежедневно делать ротацию: хранить последние 7 ротированных файлов, остальные удалять, пока размер лога файла не превысит 100 МБ.
Основные директивы управления и обработки логов можно посмотреть в справке этой команды.
(А вообще у postgres-а в его конфиге есть параметры ротации его лог-файлов, уровней логирования и т.п. ).
- ручной запуск выполняется командой:
logrotate -f /etc/logrotate.d/postgresql-common
(при этом тестовый запуск для проверки работы выполняется с ключом -d)
- автоматический: задание на автоматический запуск создается по умолчанию в файле /etc/cron.daily/logrotate.
Если изучить его содержимое, мы увидим, что идет запуск logrotate, который читает все файлы в директории /etc/logrotate.d/ и выполняющий для каждого из них ротацию. По аналогии ротацию можно настроить и для других сервисов.
- общие параметры logrotate хранятся тут: /etc/logrotate.conf
добавьте в планировщик, выполнив команду crontab -e:
0 0 * * * /usr/sbin/logrotate -f /etc/logrotate.conf
Или скриптом, для ротации всех логов (скрипт можно адаптировать под свою систему):
#!/bin/bash
# Установить logrotate, если он не установлен
# sudo apt-get install logrotate -y
# Создать пользовательский файл конфигурации logrotate
echo "/var/log/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 root root
}" | sudo tee /etc/logrotate.d/custom_logs
# Проверить конфигурацию logrotate
sudo logrotate --debug /etc/logrotate.conf
b) Также не забываем про журналы системы, используем команду journalctl:
# узнать занимаемое место логами журнала системы:
journalctl --disk-usage
root@rx:/srv/DirectumLauncher# journalctl --disk-usage
Archived and active journals take up 3.9G in the file system.
# сжать по размеру:
journalctl --vacuum-size=100M
# сжать по дате:
journalctl --vacuum-time=3d
Можно и нужно ограничить его параметрами в конфигурации journalctl:
открыв редактором файл /etc/systemd/journald.conf изменить или добавить строки:
SystemMaxUse=200M — установить максимальный размер логов;
MaxRetentionSec=7d — указать, через сколько дней логи будут удалены;
для применения настроек перезапустите сервис:
sudo systemctl restart systemd-journald
c) Если мало места на диске и хочется выполнять очистку устаревших архивов логов системы, то можно просто в crontab прописать команду, пусть ищет и чистит) - в то время как сами логи не следует удалять, чтобы избежать ошибок с работой некоторых служб:
# вводим команду crontab -e
# добавляем расписание и команду для выполнения:
0 0 * * * find /var/log \( -name "*.[0-9]" -o -name "*.*.[0-9]" -o -name "*.gz" \) -exec rm {} \; && find /var/log/ -type f -name "*log" -exec cp /dev/null {} \;`
#(в принципе по аналогии команду можно применить к любой другой папке поправив маски файлов).
d) Чистим логи или устаревшие файлы ваших программ:
По аналогии с удалением системных логов, этот процесс можно автоматизировать с помощью bash скрипта, например, вам необходимо иногда чистить каталог временных файлов, загрузки или какую то общую папку, которая некритична, но место занимает:
#!/bin/bash
# Укажите путь к нужной директории и срок хранения файлов в днях
TARGET_DIR="/home/user/downloads"
DAYS=30
# Команда для удаления файлов старше указанного количества дней
find "$TARGET_DIR" -type f -mtime +$DAYS -exec rm -f {} \;
echo "Файлы старше $DAYS дней были удалены из $TARGET_DIR"
#данный скрипт удалит рекурсивно содержимое директории /home/user/downloads файлов старше 30 дней.
# или еще проще: сразу в планировщик одной командой:
# 0 2 * * * find /home/user/downloads/ -type f -mtime +30 -exec rm -f {} \;
Пример скрипта для очистки логов DirectumRX с архивацией и хранением определенное количество дней:
#!/bin/bash
current_date=$(date +%Y-%m-%d)
# Путь к папке с логами DirectumRX
logs_path=/srv/data/logs
# Путь, куда архивировать бэкапы
backup_path=/srv/data/archive/logs_backup
log_file=backup.log
touch $backup_path/"$current_date"'_'$log_file
##Создаём новую запись в журнале##
echo "-------------$(date "+%d-%m-%Y")-------------" >> $backup_path/"$current_date"'_'$log_file
# Пакуем в архивы
tar -czf $backup_path/'logs_'"$current_date"'.tgz' $logs_path;
echo "$(date "+%d-%m-%Y") Архив 'logs_'$current_date'.tgz' создан в $backup_path" >> $backup_path/"$current_date"'_'$log_file;
# Удаляем старые логи и архивы
if [[ -n $(find "$backup_path" -type f -name "*$current_date*") ]]; then
echo "$(date "+%d-%m-%Y") Папка $backup_path очищена!" >> $backup_path/"$current_date"'_'$log_file;
find $logs_path -type f -mtime +3 -delete
else
echo "$(date "+%d-%m-%Y") Архив $logs_path не создан!" >> $backup_path/"$current_date"'_'$log_file;
fi
find $backup_path -type f -mtime +3 -delete
Ну а как делается очистка логов DirectumRX в ОС Windows, как вариант, вы можете почитать статью, там уже достаточно рассмотрено подробно: https://club.directum.ru/post/411
Не секрет, что самой популярной и производительной СУБД под Linux является PostgreSQL
Часто, на проектах на этапе внедрения или на тестовых серверах необходимо быстро настроить автоматическое резервное копирование БД, когда нет еще требований к отказоустойчивости, репликации, нет плана DRP, и т.п.
Но бэкапы хоть какие-то должны же быть, верно?
Допустим, есть сервер с БД, и нам необходимо настроить простейшее регулярное бэкапирование всех баз по расписанию, на отдельный раздел диска или сетевое хранилище.
В PostgreSQL есть встроенные утилиты:
Приведу пример простого скрипта который забэкапит все базы кроме системных с помощью pg_dump:
#!/bin/bash
# Параметры подключения к PostgreSQL
PG_HOST="localhost"
PG_PORT="5432"
PG_USER="postgres"
PG_PASSWORD="postgres"
export PG_PASSWORD
BACKUP_DIR="/srv/backups/postgres"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
# Создаем директорию для бэкапов, если её нет
mkdir -p "$BACKUP_DIR/$DATE"
# Получаем список баз данных, исключая системные
DATABASES=$(psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -t -c "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1', 'postgres');")
# Проверяем, есть ли базы для бэкапа
if [ -z "$DATABASES" ]; then
echo "No databases to backup."
exit 1
fi
# Делаем бэкап каждой базы с архивацией:
for DB in $DATABASES; do
echo "Backing up $DB..."
pg_dump -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -Fc "$DB" | gzip > "$BACKUP_DIR/$DATE/$DB.dump.gz"
# Проверяем успешность выполнения
if [ $? -eq 0 ]; then
echo "Backup of $DB completed successfully."
else
echo "Backup of $DB failed!"
exit 1
fi
done
# Опционально: удаляем старые бэкапы (храним последние 30 дней)
find "$BACKUP_DIR" -type d -mtime +30 -exec rm -rf {} ;
echo "All backups completed! Location: $BACKUP_DIR/$DATE"
Добавьте скрипт в планировщик, чтобы он работал, например, в период "технологического окна", когда активность системы минимальная:
**0 2 * * * /usr/share/pg_dump_backup.sh > /var/log/postgres_backup.log 2>&1
Скрипт попроще, когда надо бэкапить только одну БД:
#!/bin/bash
PGPASSWORD=youpassword
export PGPASSWORD
pathB=/mnt/backups
dbUser=pgadmin
database=drx
find $pathB \( -name "*-1[^5].*" -o -name "*-[023]?.*" \) -ctime +30 -delete
pg_dump -U $dbUser $database | gzip > $pathB/pgsql_$(date "+%Y-%m-%d").sql.gz
unset PGPASSWORD
Пример скрипта, который проверяет использование диска и выводит предупреждение, если оно превышает пороговое значение:
#!/bin/bash
# Установите порог использования диска в процентах
THRESHOLD=90
# Путь для мониторинга
DISK="/"
# Получаем текущее использование диска
USAGE=$(df -h "$DISK" | grep -vE '^Filesystem' | awk '{ print $5 }' | sed 's/%//g')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "Внимание: Использование диска превысило $THRESHOLD%. Текущая загрузка: $USAGE%."
# Можно добавить уведомление по email или другой метод оповещения
else
echo "Использование диска в пределах нормы: $USAGE%."
fi
Автоматическая проверка подключения к сети, с помощью "ping":
#!/bin/bash
#SERVER="IP адрес сервера, который хотелось бы проверять на доступность"
SERVER="192.168.3.100"
# Выполняем команду ping
if ping -c 1 "$SERVER" &> /dev/null
then
echo "Сеть доступна."
else
echo "Нет подключения к ресурсу $SERVER."
fi
Как вариант, можно добавить файлы скриптов в директорию /etc/profile.d/ тогда при каждом входе в систему будете получать сообщение о статусе, например, в Ubuntu эта информация и так есть, при каждом входе, а вот в Astra Linux например, будет полезна.
А лучше использовать MobaXterm, там есть Remote monitoring, который покажет все что надо:
Определите 10 самых больших файлов в системе:
find / -type f -exec du -h {} + | sort -rh | head -10
# или используйте утилиту ncdu: apt install ncdu
Проверим дисковое пространство:
df -h | awk '$5+0 > 50 {print}' | grep /dev
#(смотрим все /dev где утилизация более 50%)
Смотрим проблемы в syslog:
egrep "error|fail" /var/log/syslog
# и в реальном времени:
tail -f /var/log/syslog | grep --color=auto -E "error|warn|critical"
Проверка всех открытых сетевых портов:
ss -tulnp | grep LISTEN
# или еще нагляднее с подключениями:
ss -tulnp | grep LISTEN && lsof -i | grep TCP
Допустим, вам требутеся выполнить поиск сразу по всем логам в папке где есть ключевое слово "Error" в реальном времени, если надо "ловить" появление ошибки, когда что-то тестируешь/проверяешь.
(Например, для тех, кто хранит логи всех сервисов в одной папке или нет мониторинга от DirectumRx).
Для этого можно воспользоваться утилитой tail ("портянку" можно остановить в любой момент сочетанием клавиш Ctrl+S, возобновить Ctrl+Q, а остановить вообще Ctrl+C):
user48@test48:/srv/rxdata/logs$ tail -f ./* | grep Error
Поиск в больших каталогах с большим количеством файлов, используя параллельный запуск grep, для повышения производительности этого поиска:
find /srv/data/logs -type f | xargs -P 12 grep "Error"
Хочется быстро посмотреть настройки postgresql.conf, но только активных параметров, тогда команда:
grep -v "^#" /etc/postgresql/14/main/postgresql.conf
Смотрим, сколько подключений по ssh на данный момент:
netstat -lnpta | grep ssh | egrep "TIME_WAIT | CLOSE_WAIT | ESTABLISHED"
Представьте, что вам нужно на сервере для каждого сервиса создать подпапку для хранения логов каждого сервиса, можно это вручную сделать через mc и F7, но проще одной командой:
mkdir -p /srv/data/logs {CCS,DOS,GenericService,IndexingService,IntegrationService,JSH,LogService,
PreviewService,PreviewStorage,ReportService,RxCmd,SS,WBS,WPS,Worker,webserver,webclient,sungeropublicapi} && ls -la /srv/data/logs/
Краткий вывод запущенных docker-контейнеров:
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.RunningFor}}\t{{.Ports}}'
причем `\t{{.Ports}}` если убрать, будет выглядеть еще лаконичнее, ведь по сути чаще всего нужно увидеть имя, и статус контейнера.
Если необходимо быстро достать какой-то лог файл, с linux сервера, но работаете вы под ПК с windows, то можно обойтись одной командой scp. Открываем cmd, подключаемся, введя пароль и сразу получаем нужный файл:
scp drx@10.17.5.17:/srv/data/logs/DRX-integrationservice.IntegrationService.2024-11-25.log C:\Users\DRX1\Desktop\
# думаю что из контекста команды тут понятно какой лог забираем и куда сохраняем у себя
Пользоваться alias очень просто, достаточно авторизоваться под своей учетной записью в OS, либо работая под root, создать alias-ы часто используемых команд.
Псевдонимы помогают сократить длинный список связанных команд до более простой формы, пример:
alias update='sudo apt update -y && sudo apt upgrade -y'
т.е. в следующий раз набрав в консоли update, получим выполнение соответствующих команд.
(не рекомендуется использовать `apt upgrade` на продуктовых серверах, есть риск получить кирпич);
- команда ls с параметрами, выводящими в том числе и файлы, начинающиеся с точки, упростим до `ls_hid`:
alias ls_hid='ls -lh -d .* --color=auto'
- используйте для быстрого поиска истории команд, например `root@ubuntu:/# gh {что ищем}`:
alias gh='history|grep'
- отсортировать все файлы в выводе команды ls по размеру:
alias lsrt='ls -hs1SF'
- полная информация по блочным устройствам:
alias lsblk='lsblk -o size,NAME,LABEL,MOUNTPOINT,FSTYPE,FSAVAIL,FSUSE%,OWNER,GROUP,MODE,UUID'
alias drxup='/srv/DirectumLauncher/do.sh all up' - тут все понятно;
alias ctop='docker run --rm -ti -v /var/run/docker.sock:/var/run/docker.sock quay.io/vektorlab/ctop:latest' - удобная утилита "ctop" для вывода статистики работы docker, вместо docker stats.
Чтобы псевдонимы команд стали постоянными, добавим созданные alias-ы в конец файла .bashrc текущего пользователя:
nano ~/.bashrc и чтобы они стали доступны к применению сразу, введите source ~/.bashrc
Команда alias покажет список, а команда unalias удалит ненужный.
Команда "at" позволяет планировать задания в интерактивном режиме, используя следующий синтаксис:
at [runtime] (at 12:30) или например (at 10:00 PM)
В большинстве дистрибутивов этот сервис уже установлен, но если нет, установите: sudo apt update -y && sudo apt install at -y
например, запланируем перезапуск всех сервисов DirectumRX командой ./do.sh all up на 12:30:
root@rx:/srv/DirectumLauncher# at 12:30
warning: commands will be executed using /bin/sh
at Fri May 30 12:30:00 2025
at> /srv/DirectumLauncher/do.sh all up
at> <EOT>
job 5 at Fri May 30 12:30:00 2025
#(Также можно указать планирование заданий на определенную дату: at 00:10PM 2025-05-31)
При выполнении этой команды открывается интерактивное приглашение, в котором можно ввести команды, которые необходимо выполнить в указанное время. Кроме того, команда выводит предупреждение, указывающее на оболочку (например, /bin/sh), которая будет использоваться для выполнения запланированного задания.
Чтобы сохранить запланированное задание и выйти из интерактивного окна, нажмите ctrl+D .
Если вы хотите отменить задание до его сохранения, то можете использовать ctrl+C.
Например, мы передумали и хотим отменить задание (которое ранее уже все таки ввели): тогда для этого используется команда atrm с указанием номера задания:
root@rx:/srv/DirectumLauncher# atrm 5
# посмотреть список запланированных заданий: `at -l` (или `atq`)
root@rx:/srv/DirectumLauncher# at -l
4 Fri May 30 12:20:00 2025 a root
# и посмотреть содержимое отложенного задания (`at -c [job_number]`):
root@rx:/srv/DirectumLauncher# at -с 4
# команда выведет подробный список работы скрипта.
Подводя итог, я, как системный инженер СТАРКОВ Групп, убежден, что Bash-скрипты конечно, не панацея, но они сильно облегчают рутинные операции при работе с серверами на базе ОС Linux:
Также вы можете использовать как готовые скрипты, из общедоступных источников, так и самостоятельно написав под свои нужды уникальные скрипты.
Еще Bash удобен для освоения новичками, создание нужных скриптов не занимает много времени, скрипты легко корректируются и осваиваются, главное не бояться консоли и переменных).
А освободившееся время, которое появилось от избавления от рутины, лучше потратить, например, на изучение новых версий Directum RX.
Авторизуйтесь, чтобы написать комментарий