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

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

Реклама: @dad_admin
Download Telegram
systemd timers: сценарии, которые cron не умеет

Часто cron хватает для простого раз в день, но когда расписание становится хитрым - systemd timers выигрывают. Покажу несколько кейсов, которые на cron делать больно, а здесь - просто.

1️⃣ Только в рабочие дни, с 9:00 до 18:00. Хотим, чтобы скрипт мониторинга нагрузки запускался каждые 15 минут в будни, но не ночью и не в выходные: /etc/systemd/system/load-check.timer


[Timer]
OnCalendar=Mon..Fri *-*-* 09..18/15:00


Mon..Fri - только будни;
09..18/15:00 - каждые 15 минут с 9:00 до 18:00.

Аналог на cron выглядел бы как несколько строк с костылями.

2️⃣ Persistent=true - выполнение пропущенных задач. Задача должна выполняться раз в день, даже если сервер был выключен ночью.


[Timer]
OnCalendar=daily
Persistent=true


Если сервак в оффлайне, при старте systemd увидит пропущенное выполнение и запустит задачу.
У cron такого поведения нет - выключил машину, задача пропала.

3️⃣ Замороченные расписания - раз в час, но не в обед. Допустим, хотим запускать скрипт синхронизации каждые 60 минут, но исключить обеденный перерыв (с 12 до 13):


[Timer]
OnCalendar=Mon..Fri *-*-* 09..11:00,13..18:00


Здесь мы задали диапазоны часов с дыркой.

4️⃣ Несколько расписаний для одной задачи. Хочется иметь и ночной запуск (2:00), и дополнительный в пятницу вечером:


[Timer]
OnCalendar=*-*-* 02:00:00
OnCalendar=Fri *-*-* 19:00:00


В одном таймере можно указать несколько OnCalendar.

5️⃣ Контроль за пропусками и сбоями. Если критичный скрипт не отработал, мы хотим это видеть. Добавим OnFailure: /etc/systemd/system/backup.service


[Unit]
Description=Nightly backup job
OnFailure=alert.service


Если бэкап упадет, то сразу вызовется alert.service (например, отправка сообщения в телегу).

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍7
Перехват stdout/stderr отдельных функций и подпрограмм

Обычно мы перенаправляем вывод глобально: myfunc >out.log 2>err.log. Но что, если нужно внутри скрипта гибко ловить stdout/stderr отдельных функций и даже подпрограмм, не ломая общий вывод? Тут могут помочь динамические файловые дескрипторы через exec {fd}>.

▪️ Пример 1. Логирование только stdout функции


logfile="stdout.log"

myfunc() {
echo "info: started"
echo "debug: internal"
echo "error: fail" >&2
}

exec {fd}> "$logfile" # создаем FD
myfunc 1>&$fd # stdout -> в файл, stderr остаётся на экран
exec {fd}>&- # закрываем FD


stdout (info, debug) уйдет в stdout.log;
stderr (error) появится в терминале.

▪️ Пример 2. Перехват stderr подпрограммы


errlog="stderr.log"

exec {fd}> "$errlog"
{ ls /root; echo "done"; } 2>&$fd
exec {fd}>&-


Ошибки от ls /root попадут в stderr.log, а «done» останется в терминале.

▪️ Пример 3. Отдельный канал для «отладки» внутри функции. Иногда хочется иметь третий тип вывода, помимо stdout/stderr.


exec {dbg}> debug.log # отдельный канал

mycalc() {
echo "42" # обычный результат
echo "step1 ok" >&$dbg
echo "step2 ok" >&$dbg
}

result=$(mycalc)
echo "result = $result"
exec {dbg}>&-


Так можно вести невидимый debug-лог параллельно с обычной работой.

▪️ Пример 4. Подмена stdout на время вызова


mycmd() { echo "normal out"; }

{
exec {fd}> redirected.log
mycmd >&$fd
exec {fd}>&-
}
echo "done"


Прием позволяет временно заменить stdout и потом вернуть его обратно.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Не пропускаем!

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁10
Быстрый поиск и исправление команд из истории

Многие знают, что в bash есть история команд (history, !, !!), но мало кто активно пользуется экспресс-заменой.

▪️ Замена в последней команде: ^old^new

Если вы ввели команду с ошибкой, не нужно её перепечатывать целиком. Просто используйте конструкцию: ^ошибка^правильно

Пример:


sl -l #неверная команда

bash: sl: command not found

^sl^ls # исправление
ls -l


Bash сам возьмет последнюю команду из истории и заменит в ней sl на ls.

▪️ Более гибкая работа с историей: !

!! - повторяет последнюю команду
!ls - повторяет последнюю команду, начинавшуюся с ls
!$ - последний аргумент предыдущей команды
!* - все аргументы предыдущей команды

Пример:


tar -xf archive.tar.gz /tmp
cd !$
cd /tmp


▪️ Ctrl+R для интерактивного поиска

нажмите Ctrl+R и начните печатать часть команды - bash покажет совпадение из истории.
Нажимайте Ctrl+R ещё раз, чтобы найти следующее.

BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8🫡1
Скрипт-сортер медиа по датам

Хаос в папке с фотографиями и видео? Все вперемешку: отпуск 2018-го рядом с мемами 2024-го. Можно навести порядок одним скриптом.

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


sorted/
├── 2018/
│ ├── 01/
│ └── 07/
├── 2020/
│ ├── 12/
└── 2024/
├── 02/
└── 05/


Основание - дата создания файла (или модификации, если EXIF не нужен).

🛠 Скрипт


#!/bin/bash

SRC_DIR=${1:-"./media"} # откуда берем файлы
DST_DIR=${2:-"./sorted"} # куда складываем

mkdir -p "$DST_DIR"

find "$SRC_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.mp4" -o -iname "*.mov" \) | while read -r file; do
# получаем дату модификации файла (год и месяц)
year=$(date -r "$file" +%Y)
month=$(date -r "$file" +%m)

# создаем директорию и переносим
target="$DST_DIR/$year/$month"
mkdir -p "$target"

echo "→ $file → $target/"
mv "$file" "$target/"
done


▪️ Запуск


chmod +x media_sorter.sh
./media_sorter.sh ./Camera ./SortedMedia


🌟 Дополнительно

Если нужен EXIF (реальная дата съёмки фото, а не модификации файла) → используем exiftool:


exiftool '-FileName<CreateDate' -d "%Y/%m/%Y-%m-%d_%H-%M-%S%%-c.%%e" ./media


⚠️ Для видео часто EXIF нет, но можно использовать ffprobe (часть ffmpeg) для даты.

Такой скрипт удобно запускать перед бэкапом в облако - сразу порядок в медиатеке.

BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Множественные команды одной строкой

Одна из недооцененных фич bash - фигурные скобки {}. Она позволяет за одну строку сгенерировать множество вариантов команды.

▪️ Пример с файлами


touch file-{1,2,3}.md


Создаст сразу три файла:


file-1.md
file-2.md
file-3.md


▪️ Полезные варианты

1️⃣ Диапазоны чисел


mkdir backup-{2022..2025}


Создаст папки:


backup-2022 backup-2023 backup-2024 backup-2025


2️⃣ Диапазоны букв


touch part-{a..d}.txt

part-a.txt part-b.txt part-c.txt part-d.txt


3️⃣ Комбинации (картезианское произведение)


echo {dev,staging,prod}-{us,eu,asia}

dev-us staging-us prod-us dev-eu staging-eu prod-eu dev-asia staging-asia prod-asia


4️⃣ Множественные команды


cp config.{yml,json} /etc/myapp/


Скопирует оба файла за раз.

▪️ Фишки для автоматизации

1️⃣ Генерация тестовых данных:


touch user-{001..100}.log


сразу 100 файлов

2️⃣ Быстрое клонирование директорий:


cp -r src{,-backup}


создаст копию src-backup без лишнего ввода.

3️⃣ Комбинации шаблонов:


mv report_{2022..2024}_{01..12}.csv /data/reports/


сразу раскладывание отчётов по месяцам и годам.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
Букмарк-система для директорий

Если вы часто прыгаете между одними и теми же каталогами, держать их пути в голове (или копировать через cd /long/very/deep/path/...) - мучение. Решение: написать мини-систему закладок для директорий.

🛠 Скрипт j (добавьте это в свой ~/.bashrc или ~/.zshrc):


# Файл для хранения закладок
J_BOOKMARKS=~/.j_bookmarks

# Функция j
j() {
# без аргументов - показать список закладок
if [[ $# -eq 0 ]]; then
cat "$J_BOOKMARKS" 2>/dev/null || echo "Закладок пока нет."
return
fi

case "$1" in
+) # добавить закладку для текущей директории
echo "$2:$(pwd)" >> "$J_BOOKMARKS"
echo "Добавлено: $2 → $(pwd)"
;;
-) # удалить закладку
grep -v "^$2:" "$J_BOOKMARKS" > "$J_BOOKMARKS.tmp" && mv "$J_BOOKMARKS.tmp" "$J_BOOKMARKS"
echo "Удалено: $2"
;;
*) # перейти по метке
local target
target=$(grep "^$1:" "$J_BOOKMARKS" | cut -d: -f2-)
if [[ -n "$target" ]]; then
cd "$target" || echo "Ошибка: нет доступа к $target"
else
echo "Нет закладки: $1"
fi
;;
esac
}


▪️ Использование

Добавить закладку для текущей директории:


j + myproj


сохраняет myproj: /home/user/projects/myproj

Перейти в закладку:


j myproj


мгновенный cd в /home/user/projects/myproj

Удалить закладку:


j - myproj


Посмотреть все закладки:


j


BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Bash-лайфхак: комментирование команд прямо в истории

Когда вы часто экспериментируете в терминале, история превращается в хаос - одинаковые команды, тестовые прогоны, случайные опечатки… И вот через месяц вы смотрите на history | grep rsync и думаете: "А что это я тут хотел сделать?" или какая из этих команд рабочая..

Но тут есть один простой трюк - добавляете комментарий прямо к команде, и он сохранится в истории.

🌟 Как это работает?

В bash можно писать так:


rsync -av --delete /data/ /backup/ # бэкап данных на внешний диск


В истории будет сохранена вся строка. И когда через Ctrl+R или history | grep backup вы ищете - строка находится по тексту комментария тоже!

▪️ Примеры


ssh user@host # тест сервера
docker exec -it web bash # залезть внутрь контейнера nginx
find /var/log -type f -size +100M # поиск больших логов


▪️ Полезные фишки

Можно делать свои теги:


apt update && apt upgrade # [system-maintenance]


А потом искать:


history | grep "\[system-maintenance\]"


BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12
Самурай психанул и словил дзен

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁14
Архивация только новых или измененных файлов

Как архивировать только измененные файлы без ведения отдельного списка и без сложных скриптов. Решение на самом деле простое - связка find + tar + gzip.

▪️ Проблема

Обычный tar -czf backup.tar.gz /data каждый раз сжимает все файлы → при больших каталогах это очень долго.
Хотелось бы архивировать только то, что изменилось за последний день/час.

▪️ Решение: find + tar


find /data -type f -mtime -1 -print0 | tar --null -czf backup-$(date +%F).tar.gz --files-from=-


-mtime -1 - ищет файлы, измененные за последние 24 часа
-print0 + --null - защита от пробелов в именах
--files-from=- - tar берет список файлов прямо из stdin

▪️ Вариант с часами (например, за 2 часа)


find /data -type f -mmin -120 -print0 | tar --null -czf backup-$(date +%F_%H%M).tar.gz --files-from=-


▪️ Инкрементальные архивы (только изменения с момента последнего бэкапа)


touch /tmp/last-backup
find /data -type f -newer /tmp/last-backup -print0 | \
tar --null -czf backup-$(date +%F).tar.gz --files-from=-
touch /tmp/last-backup


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Расширенные шаблоны

Есть фишки, про которые многие говорят: «я только недавно узнал, что так можно!» Одна из таких - расширенные шаблоны.

▪️ Включаем расширенные шаблоны


shopt -s extglob


Теперь доступны конструкции:

?(pattern) - 0 или 1 совпадение
*(pattern) - 0 или больше
+(pattern) - 1 или больше
@(pattern) - ровно одно из
!(pattern) - всё, кроме


▪️ Полезные примеры

1️⃣ Исключить расширение


for f in !(*.bak); do
echo "Обрабатываю $f"
done


Пробегаем по всем файлам, кроме .bak.

2️⃣ Сгруппировать несколько расширений


for img in *.@(jpg|png|gif); do
echo "Найдено изображение: $img"
done


Ловим только картинки, не заморачиваясь с длинными условиями.

3️⃣ Лестница через case


case $var in
+([0-9])) echo "Это число" ;;
?(http)://*) echo "Это URL" ;;
*.@(sh|bash)) echo "Это Bash-скрипт" ;;
*) echo "Что-то другое" ;;
esac


Можно строить почти регулярочные проверки, но быстрее и нагляднее.

4️⃣ Исключение нескольких типов


for f in !(*.log|*.tmp); do
echo "Чистый файл: $f"
done


Берём всё, кроме .log и .tmp.

5️⃣ Валидация формата прямо в if


if [[ $user == +([a-zA-Z0-9._-]) ]]; then
echo "Имя пользователя валидно"
else
echo "Некорректное имя"
fi


Короткая проверка без grep и regex.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Bash как оркестратор

Многие используют docker-compose или kubectl apply напрямую, но часто в реальной инфраструктуре требуются условные проверки, ветвления, откаты, повторные попытки. И тут bash оказывается неожиданно полезным инструментом.

▪️ Пример 1. Bash + docker-compose


#!/usr/bin/env bash
set -euo pipefail

echo "[*] Deploying database..."
docker-compose -f compose.db.yml up -d
sleep 10

echo "[*] Checking DB health..."
docker-compose exec db pg_isready -U postgres || {
echo "DB is not ready, aborting!"
exit 1
}

echo "[*] Deploying app..."
docker-compose -f compose.app.yml up -d


Скрипт запускает сначала базу, ждет, проверяет ее готовность и только потом запускает приложение. Такой контроль docker-compose сам по себе не умеет.

▪️ Пример 2. Bash + Kubernetes


#!/usr/bin/env bash
set -euo pipefail

NAMESPACE="staging"

echo "[*] Applying secrets..."
kubectl apply -f secrets.yml -n $NAMESPACE

echo "[*] Deploying app..."
kubectl apply -f app.yml -n $NAMESPACE

echo "[*] Waiting for rollout..."
kubectl rollout status deployment/myapp -n $NAMESPACE --timeout=60s || {
echo "Rollout failed, rolling back..."
kubectl rollout undo deployment/myapp -n $NAMESPACE
}


Тут добавлена проверка статуса роллаута и откат, если приложение не поднялось.

▪️ Пример 3. Управление конфигами и миграциями

Bash может быть связующим звеном:

сначала подгружаем env-настройки,
потом запускаем миграции БД,
и только если они успешны - применяем манифесты.


source .env

echo "[*] Running migrations..."
docker-compose run --rm app ./manage.py migrate || exit 1

echo "[*] Applying manifests..."
kubectl apply -f k8s/ -n $NAMESPACE


BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Сравнение конфигов на разных серверах через md5sum

▪️ Сравнение директорий по контрольным суммам


# На сервере A:
find /etc -type f -print0 \
| sort -z \
| xargs -0 md5sum > /tmp/etc-hash.txt

# На сервере B:
find /etc -type f -print0 \
| sort -z \
| xargs -0 md5sum > /tmp/etc-hash.txt


Затем можно скопировать файлы на локальный хост и сравнить:


diff -u serverA/etc-hash.txt serverB/etc-hash.txt


Отличия будут видны построчно: какие файлы отличаются и какие отсутствуют.

▪️ Более гибкий вариант

Хэшируем сразу несколько директорий и добавляем префикс хоста:


for h in server1 server2; do
ssh $h 'find /etc -type f -print0 \
| sort -z \
| xargs -0 md5sum' \
| sed "s|^|$h |"
done > all-hashes.txt


Теперь легко фильтровать:


awk '{print $2,$1}' all-hashes.txt | sort | uniq -c


Если файл совпадает на всех хостах - будет одинаковая хэш-сумма.
Если разный - сразу видно у какого сервера отличается.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9
Копирование между хостами без SCP

Сегодня поделюсь с вами альтернативным способом копирования между хостами, когда SCP недоступен или файлы лежат в приватной сети.

▪️ Отправка каталога по SSH

На источнике:


tar cz dir_to_copy \
| base64 \
| ssh user@remote "base64 -d | tar xz"


dir_to_copy упаковывается в tar.gz, кодируется base64, передается по SSH и на удаленном хосте раскодируется и распаковывается.

▪️ Копирование через буфер (без SCP и SSH)

На источнике:


tar cz myfile.txt | base64


Копируем вывод в буфер и затем на приемнике:


base64 -d | tar xz


Вставляем скопированное содержимое и файл восстановится
Работает даже там, где SCP недоступен.

▪️ Обмен папками между хостами без сети

Через tmux buffer или screen можно передавать данные вообще без файлов и SSH, просто через терминал. Пример в tmux:

На сервере А:


tar cz project | base64 | tmux load-buffer -


На сервере Б:


tmux save-buffer - | base64 -d | tar xz


🌟 Для больших архивов можно добавить pv и тогда будет видно прогресс:


tar cz bigdir | pv | base64 | ssh host "base64 -d | tar xz"


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🗿1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁15🔥3
PROMPT_COMMAND

Недавно на форуме arch linux увидел такую штуку:


export PROMPT_COMMAND='[[ $curdir != $PWD ]] && ls -a; curdir=$PWD'


при каждом входе в новую директорию автоматически вызывается ls -a.

А все дело в переменной окружения PROMPT_COMMAND - bash выполняет ее перед выводом нового приглашения. Если разобраться, можно превратить её в инструмент автоматизации.

▪️ Базовые сценарии

📍 Автолистинг при смене директории


PROMPT_COMMAND='[[ $lastdir != $PWD ]] && ls; lastdir=$PWD'


ls срабатывает только если реально поменяли директорию.

📍 Показ текущей git-ветки


PROMPT_COMMAND='branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null); PS1="[\u@\h \W${branch:+ ($branch)}]\\$ "'


приглашение (PS1) динамически обновляется: добавляет (ветка) только в репозитории.

📍Отображение количества фоновых задач


PROMPT_COMMAND='jobs_count=$(jobs -p | wc -l); PS1="[jobs:$jobs_count] \u@\h:\w\$ "'


рядом с промптом видим, сколько задач выполняется в фоне.

▪️ Продвинутые хаки

📍 Время последней команды


PROMPT_COMMAND='PS1="[\t] \u@\h:\w\$ "'


каждый раз в начале промпта вставляется текущее время.

📍 Звуковой сигнал при ошибке


PROMPT_COMMAND='[ $? -ne 0 ] && echo -ne "\a"'


если последняя команда завершилась ошибкой (exit code != 0), терминал пищит.

📍История + логирование всех команд


PROMPT_COMMAND='history -a; history -c; history -r'


история сохраняется сразу (не только при выходе из shell), что полезно при одновременных сессиях.

▪️ Комбо вариант


PROMPT_COMMAND='
[[ $lastdir != $PWD ]] && ls; lastdir=$PWD;
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null);
jobs_count=$(jobs -p | wc -l);
PS1="[jobs:$jobs_count ${branch:+git:$branch}] \u@\h:\w\$ "
'


- при смене директории автоматом делается ls
- в промпте видно количество фоновых задач
- в git-репозитории показывается текущая ветка

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Cтатистика по сетевым соединениям

1️⃣ Быстрая сводка: сколько вообще соединений. Используем ss - он современнее netstat и есть почти везде.


ss -s


Пример вывода:


Total: 1024 (kernel 2048)
TCP: 512 (estab 200, closed 10, orphaned 0, synrecv 0, timewait 55/0), ports 0
UDP: 256
RAW: 0


2️⃣ Топ IP по количеству соединений (TCP). Самый распространенный прием - взять список активных соединений и посчитать, какие удаленные IP встречаются чаще всего.


ss -tn state established '( dport != :22 )' \
| awk '{print $5}' \
| sed 's/:[0-9]*$//' \
| sort \
| uniq -c \
| sort -nr \
| head -n 20


ss -tn state established - TCP, только установленные соединения;
$5 в выводе ss - удалённый адрес (remote:port); sed убирает порт;
uniq -c | sort -nr - считаем и сортируем по убыванию.

Пример вывода:


120 203.0.113.42
87 198.51.100.10
45 10.0.0.5
...


3️⃣ Топ удаленных портов (куда подключаются клиенты). Иногда важно понять, на какие порты чаще всего идут входящие соединения:


ss -tn state established \
| awk '{print $4}' \
| sed 's/.*://; s/::ffff://g' \
| sort \
| uniq -c \
| sort -nr \
| head -n 20


Здесь мы берем локальный адрес $4 и вычленяем порт.

Пример вывода:


340 443
200 80
50 22
...


4️⃣ Показать top IP + процесс (PID). Хочется не только IP, но и процесс, который держит соединения:


ss -tnp | awk '/ESTAB/ { split($6, a, ":"); ip=a[1]; match($0, /pid=[0-9]+,/, m); pid=(m[0]=="")? "?" : substr(m[0],5,length(m[0])-5); print ip, pid }' \
| sort | uniq -c | sort -nr | head -n 30


ss -tnp выводит PID/program в конце строки, мы парсим это и группируем.

Пример вывода:


50 203.0.113.42 2345
30 198.51.100.10 5012
...


Интерпретация: 203.0.113.42 имеет 50 соединений, принадлежащих процессу с PID 2345.

5️⃣ Однострочник: показать какие процессы создают больше всего соединений. Если нужно быстро понять, какие программы держат трафик:


ss -tnp | awk '/ESTAB/ { if (match($0, /pid=([0-9]+),/ , m)) { pid=m[1]; sub(/^.*pid=[0-9]+, /,""); proc=$0; split(proc,p," "); print pid, p[1] } }' \
| sort | uniq -c | sort -nr | head -n 20


Результат - счетчик + PID + имя процесса.

6️⃣ Оценка трафика (байты) - через iptables счётчики. ss не всегда дает удобную сумму байт на IP. Для оценки трафика по IP удобно использовать iptables счетчики (если вы можете изменять правила). Создадим правило для счёта байт/пакетов входящего/исходящего трафика:


# создать chain для мониторинга (однократно)
sudo iptables -N MONITOR 2>/dev/null || true
sudo iptables -I INPUT -j MONITOR
sudo iptables -I OUTPUT -j MONITOR

# добавить правило для конкретного IP (пример)
sudo iptables -I MONITOR -s 203.0.113.42 -j ACCEPT

# посмотреть счётчики
sudo iptables -L MONITOR -vn --line-numbers


Вывод покажет количество пакетов/байтов для каждого правила - можно парсить и сохранять в CSV.

7️⃣ Несколько полезных примеров про запас

Топ слушающих сокетов (портов на сервере):


ss -lnpt | awk '{print $4}' | sed 's/.*://; /^[[:space:]]*$/d' | sort | uniq -c | sort -nr


Топ активных UDP-адресов:


ss -un | awk '{print $5}' | sed 's/:[0-9]*$//' | sort | uniq -c | sort -nr | head


Полный список соединений с PID и программой:


ss -tnp | sed 's/ */ /g' | awk '{print $1, $4, $5, $6}'


BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2
Терпите.

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁8🔥3
Как выполнить команду без следов

Многие знают, что bash сохраняет введенные команды в ~/.bash_history. Но иногда, когда требуется ввести пароль в команде или использовать одноразовый токен, хочется, чтобы этого не было в истории.

📌 Решение: начни команду с пробела. Если в .bashrc (или глобально в /etc/bash.bashrc) включена опция:


HISTCONTROL=ignoreboth


то любая команда, набранная с пробелом в начале, не попадет в историю.

▪️ Пример:


# обычная команда - сохраняется в истории
echo "hello"

# команда с пробелом - не будет в history
echo "secret run"


▪️ Полезные комбинации с HISTCONTROL

ignoredups - не сохранять дубликаты подряд.
ignorespace - не сохранять команды, начинающиеся с пробела.

Можно управлять этим через .bashrc:


export HISTCONTROL=ignoreboth
export HISTSIZE=5000
export HISTFILESIZE=10000


BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3