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

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

Реклама: @dad_admin
Download Telegram
Динамическая замена строк в переменных без внешних утилит

В 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/noscript.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
noscript:
- echo "Сборка проекта..."
- make build # Команда сборки

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

deploy:
stage: deploy
noscript:
- 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/noscript.sh" .sh # Выведет: noscript


📌 Это полезно, например, при генерации логов:


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="./noscript.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]
Denoscription=Автоматическое монтирование сетевой папки
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
Создание зашифрованных контейнеров с cryptsetup и LUKS

LUKS (Linux Unified Key Setup) + cryptsetup позволяют создавать зашифрованные контейнеры, доступ к которым можно получить только после ввода пароля.

📦 Что можно хранить в зашифрованном контейнере?

🔹 Личные файлы и документы
🔹 Бэкапы с конфиденциальными данными
🔹 Временные файлы, которые нужно удалять без следов

🧑‍💻 Создание зашифрованного контейнера

1️⃣ Создаем файл-контейнер. Допустим, нам нужен контейнер размером 1 ГБ:


dd if=/dev/zero of=secure.img bs=1M count=1024


2️⃣ Настраиваем LUKS-шифрование


cryptsetup luksFormat secure.img


⚠️ Важно: Этот шаг удалит все данные в файле!

При появлении запроса укажите сложный пароль для доступа к контейнеру.

3️⃣ Открываем зашифрованный контейнер


cryptsetup luksOpen secure.img secure_container


Теперь в системе появился виртуальный шифрованный диск /dev/mapper/secure_container.

4️⃣ Форматируем в файловую систему


mkfs.ext4 /dev/mapper/secure_container


5️⃣ Монтируем и используем


mkdir /mnt/secure
mount /dev/mapper/secure_container /mnt/secure


Теперь файлы, скопированные в /mnt/secure, будут автоматически зашифрованы.

🚫 Отключение контейнера. Чтобы отключить зашифрованный диск:


umount /mnt/secure
cryptsetup luksClose secure_container


🏠 Автоматическое подключение по паролю. Можно хранить ключ для автоматического подключения в файле:


dd if=/dev/random of=/root/luks.key bs=1 count=256
chmod 600 /root/luks.key
cryptsetup luksAddKey secure.img /root/luks.key


Теперь можно открыть контейнер без ввода пароля:


cryptsetup luksOpen secure.img secure_container --key-file /root/luks.key


BashTex 📱 #linux #security
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍5
Скрипт автоматического создания и удаления временных файлов

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

Создание временных файлов и директорий. Используем mktemp:


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


Или создаем временную папку:


TEMP_DIR=$(mktemp -d)
echo "Временная папка: $TEMP_DIR"


📂 Автоматическое удаление. trap удалит временные файлы при завершении скрипта:


#!/bin/bash
TEMP_FILE=$(mktemp)
trap "rm -f $TEMP_FILE" EXIT

echo "Создан временный файл: $TEMP_FILE"
sleep 5 # Эмуляция работы скрипта


trap выполняет rm -f $TEMP_FILE при завершении скрипта – даже если он аварийно прерван.

👩‍🎨 Скрипт для очистки старых временных файлов. Удалим файлы старше 1 дня в /tmp:


find /tmp -type f -mtime +1 -delete


Для папок:


find /tmp -type d -empty -mtime +1 -exec rmdir {} \;


🤖 Добавим в crontab ежедневную очистку /tmp:


0 3 * * * find /tmp -type f -mtime +1 -delete


В 3 часа ночи старые временные файлы будут автоматически удаляться.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Вошли и вышли, приключение на 15 минут 🪞

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁17🫡1
stdbuf - отключение буферизации вывода в командах

Когда выполняешь команды в терминале, их вывод иногда задерживается из-за буферизации. Это мешает при логировании, мониторинге в реальном времени и пайпах. stdbuf решает эту проблему, управляя буферизацией стандартного ввода, вывода и ошибок.

🚪 Как отключить буферизацию? Запустим ping, но без задержек в выводе:


stdbuf -oL ping 8.8.8.8


-oL - отключает буферизацию вывода (line-buffered mode). Теперь каждая строка появляется сразу.

Для ошибок (stderr):


stdbuf -eL some_command


👀 Использование с пайпами. Некоторые команды задерживают вывод в пайпах. Например, grep в цепочке:


ping 8.8.8.8 | grep "time="


Ничего не показывает? Это из-за буферизации! Исправляем:


ping 8.8.8.8 | stdbuf -oL grep "time="


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

1️⃣ Логирование в реальном времени


stdbuf -oL tail -f /var/log/syslog | grep "error"


2️⃣ Скрипт без задержек в выводе


#!/bin/bash
stdbuf -o0 my_noscript.sh


-o0 полностью отключает буферизацию.

3️⃣ Буферизация при вводе


stdbuf -i0 -o0 -e0 cat


Позволяет мгновенно обрабатывать ввод/вывод.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
This media is not supported in your browser
VIEW IN TELEGRAM
Ты бл#, ты сказал, что ты шаришь в этой теме..

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13😁11🎅4👨‍💻1🫡1🎄1
Вывод списка установленных пакетов по дате

Хочешь узнать, какие пакеты и когда были установлены в системе? В Ubuntu это можно сделать с помощью dpkg и awk.

Базовый способ. Чтобы получить список всех установленных пакетов с датой их установки, используй:


grep " install " /var/log/dpkg.log


Этот лог содержит записи о каждом установленном или обновлённом пакете.

🗯 Вывод с сортировкой. Если нужен полный список с датами и сортировкой:


awk '$3 == "install" {print $1, $2}' /var/log/dpkg.log | sort


$1 - дата установки
$2 - имя пакета
sort упорядочивает по дате

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


2025-03-01 coreutils
2025-03-02 openssh-server
2025-03-04 htop


📌 Фильтр по определённому дню. Допустим, надо узнать, что было установлено 3 февраля 2025 года:


grep "2025-02-03" /var/log/dpkg.log | grep "install"


📂 Вывод списка недавно установленных пакетов


zgrep " install " /var/log/dpkg.log* | tail -20


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥3👨‍💻3
Ну мы

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁15