В Linux можно копировать собранные файлы так, чтобы не менять файл назначения, если новая версия фактически такая же!
Для этого у
Перед установкой
Это принципиально отличается от обычного копирования поверх файла:
Даже если результат сборки идентичен предыдущему, лишняя перезапись может изменить метаданные файла и запустить всё, что следит за его изменением.
С
Причём
🔥
🚪 Linux Ready | #совет
Для этого у
GNU install есть опция -C (--compare):install -C -m 0755 ./build/myapp ./bin/myapp
Перед установкой
install сравнит исходный и существующий файлы. Если содержимое и заданные атрибуты совпадают, файл назначения вообще не будет изменён.Это принципиально отличается от обычного копирования поверх файла:
cp ./build/myapp ./bin/myapp
Даже если результат сборки идентичен предыдущему, лишняя перезапись может изменить метаданные файла и запустить всё, что следит за его изменением.
С
install -C это удобно убрать прямо из Makefile или скрипта локального развёртывания:install -C -m 0755 build/myapp /usr/local/bin/myapp
Причём
install одновременно умеет выставлять права, поэтому отдельный chmod после копирования не требуется:install -C -m 0644 config.ini /etc/myapp/config.ini
install -C полезен там, где одна и та же сборка устанавливается много раз: неизменившийся файл остаётся нетронутым, а копирование и выставление прав сводятся к одной команде.Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤7🤝4🔥3
Например,
sed 's/old/new/g' file.txt заменяет все вхождения old на new, а sed -n '2p' file.txt выводит только вторую строку.На картинке — основные команды, опции и флаги
sed, а также готовые примеры для замены текста, удаления строк и редактирования файлов.Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥6🤝3❤1
Для отладки изолированного процесса необязательно заходить внутрь контейнера или менять его образ!
Linux хранит
Например, если сервис видит другую сеть, чем хост:
То же самое можно сделать с файловыми монтированиями:
А если для диагностики нужны сразу несколько namespaces:
Так можно получить
При этом
🔥
🚪 Linux Ready | #совет
Linux хранит
namespaces процесса в /proc/<PID>/ns/, а nsenter позволяет выполнить команду внутри выбранного namespace уже работающего процесса.Например, если сервис видит другую сеть, чем хост:
sudo nsenter -t 1842 -n ss -lntp
-t 1842 выбирает процесс, а -n подключает команду к его network namespace. В результате ss работает с тем же сетевым стеком, таблицами маршрутизации и интерфейсами, которые доступны целевому процессу.То же самое можно сделать с файловыми монтированиями:
sudo nsenter -t 1842 -m findmnt
А если для диагностики нужны сразу несколько namespaces:
sudo nsenter -t 1842 -m -n -p sh
Так можно получить
shell с mount, network и PID namespace нужного процесса и запускать внутри обычные ip, ss, findmnt, ps и другие диагностические инструменты.При этом
nsenter не создаёт новый namespace — он присоединяет запускаемую команду к уже существующему.nsenter особенно полезен, когда процесс изолирован namespaces, а внутри его окружения нет диагностических утилит: вместо установки инструментов туда можно зайти в нужный namespace с хоста и исследовать проблему на месте.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍7❤4🤝2
Большой файл можно клонировать почти мгновенно без полного копирования его данных!
На файловой системе с поддержкой
Новый файл получает собственное имя и метаданные, но первоначально разделяет
Когда один из файлов изменяется, файловая система копирует только затронутые блоки:
Исходный файл при этом не изменится.
Режим
Для автоматического перехода к обычному копированию используется:
Такой клон подходит для крупных артефактов сборки, наборов данных и временных рабочих копий. Он не заменяет резервное копирование и не гарантирует согласованность файлов работающих баз данных или виртуальных машин.
🔥 Используйте
🚪 Linux Ready | #совет
На файловой системе с поддержкой
reflink выполните:cp --reflink=always build.tar.zst test-build.tar.zst
Новый файл получает собственное имя и метаданные, но первоначально разделяет
extents исходного файла.Когда один из файлов изменяется, файловая система копирует только затронутые блоки:
printf 'test' >> test-build.tar.zst
Исходный файл при этом не изменится.
Режим
--reflink=always удобен для проверки: если источник и назначение находятся на разных файловых системах либо reflink не поддерживается, cp завершится ошибкой вместо незаметного полного копирования.Для автоматического перехода к обычному копированию используется:
cp --reflink=auto build.tar.zst test-build.tar.zst
Такой клон подходит для крупных артефактов сборки, наборов данных и временных рабочих копий. Он не заменяет резервное копирование и не гарантирует согласованность файлов работающих баз данных или виртуальных машин.
reflink, когда нужен быстрый независимый клон большого неизменяемого файла внутри одной поддерживаемой файловой системы.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍7❤2🤝1
В GNU/Linux есть отдельная утилита для преобразования чисел внутри текстовых потоков!
Допустим, команда или скрипт отдаёт размер в байтах:
Вместо того чтобы подключать
Причём преобразование работает и в обратную сторону — привычные размеры можно превратить в обычные числа:
Это удобно в shell-скриптах: на вход можно принимать понятные человеку 500Mi или 4Gi, а внутри работать уже с количеством байтов.
🔥
🚪 Linux Ready | #совет
Допустим, команда или скрипт отдаёт размер в байтах:
du -B1 /var/log/* | head
Вместо того чтобы подключать
awk и вручную делить значения на 1024, вывод можно сразу пропустить через numfmt:du -B1 /var/log/* | numfmt --field=1 --to=iec-i
--field=1 преобразует только первое поле каждой строки. Всё остальное остаётся на месте, поэтому numfmt удобно вставлять прямо в уже существующие пайпы.Причём преобразование работает и в обратную сторону — привычные размеры можно превратить в обычные числа:
printf '%s\n' 512Mi 2Gi |
numfmt --from=iec-i
Это удобно в shell-скриптах: на вход можно принимать понятные человеку 500Mi или 4Gi, а внутри работать уже с количеством байтов.
bytes=$(numfmt --from=iec-i <<< "4Gi")
echo "$bytes"
numfmt позволяет выкинуть из shell-скриптов самодельные конвертеры размеров: он понимает единицы, умеет работать с отдельными полями и встраивается в обычные Linux-пайпы.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍10❤5
Например,
SRE фокусируется на надёжности и эксплуатации систем, а Platform Engineering — на создании общей платформы и инструментов для продуктовых команд.На картинке — наглядное сравнение
DevOps, SRE и Platform Engineering: от разработки, тестирования и релизов до деплоя, мониторинга и эксплуатации инфраструктуры.Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍6🤝4❤1
Подключаемся к закрытым серверам через SSH ProxyJump!
В инфраструктуре серверы часто не имеют публичного IP-адреса и доступны только из внутренней сети. При этом отдельный сервер может быть доступен извне и использоваться как промежуточный SSH-узел — bastion или jump host.
Например, bastion доступен по адресу
Если bastion имеет доступ к
(адреса в примерах документационные — при повторении замените их на свои)
SSH сначала подключится к
Если SSH на bastion работает на нестандартном порту, его можно указать прямо в параметре
Для постоянной работы удобнее описать оба сервера в
После этого подключение к внутреннему серверу выполняется обычной командой:
Через тот же маршрут можно использовать
Или
Если до целевого сервера нужно пройти через несколько промежуточных узлов, их можно перечислить через запятую:
То же самое можно записать в конфигурации:
Для bastion и внутреннего сервера можно использовать разные SSH-ключи:
Приватный ключ от внутреннего сервера при этом не требуется копировать на bastion. Аутентификацию на конечном сервере выполняет локальный SSH-клиент.
Посмотреть итоговую конфигурацию, которую SSH применит для подключения, можно через:
Например, отдельно вывести основные параметры:
Если соединение не устанавливается, запускаем SSH с диагностическим выводом:
Для более подробной диагностики:
Так можно увидеть установление соединения через промежуточный узел, выбор ключей, проверку host key и этапы аутентификации.
После этого локально подключаемся к базе через порт
SSH-соединение пройдёт через bastion до внутреннего сервера, а перенаправление на
🔥
🚪 Linux Ready | #практика
В инфраструктуре серверы часто не имеют публичного IP-адреса и доступны только из внутренней сети. При этом отдельный сервер может быть доступен извне и использоваться как промежуточный SSH-узел — bastion или jump host.
Например, bastion доступен по адресу
203.0.113.10, а внутренний сервер имеет адрес 10.0.0.20. Напрямую подключиться к внутреннему серверу из внешней сети нельзя:ssh admin@10.0.0.20
Если bastion имеет доступ к
10.0.0.20:22, используем ProxyJump:ssh -J user@203.0.113.10 admin@10.0.0.20
(адреса в примерах документационные — при повторении замените их на свои)
SSH сначала подключится к
203.0.113.10, а соединение с SSH-сервером на 10.0.0.20 будет установлено через этот промежуточный узел.Если SSH на bastion работает на нестандартном порту, его можно указать прямо в параметре
-J:ssh -J user@203.0.113.10:2222 admin@10.0.0.20
Для постоянной работы удобнее описать оба сервера в
~/.ssh/config:Host bastion
HostName 203.0.113.10
User user
Host internal
HostName 10.0.0.20
User admin
ProxyJump bastion
После этого подключение к внутреннему серверу выполняется обычной командой:
ssh internal
Через тот же маршрут можно использовать
scp:scp backup.tar.gz internal:/tmp/
Или
sftp:sftp internal
Если до целевого сервера нужно пройти через несколько промежуточных узлов, их можно перечислить через запятую:
ssh -J user@gateway1,user@gateway2 admin@internal
То же самое можно записать в конфигурации:
Host internal
HostName 10.0.0.20
User admin
ProxyJump gateway1,gateway2
Для bastion и внутреннего сервера можно использовать разные SSH-ключи:
Host bastion
HostName 203.0.113.10
User jump
IdentityFile ~/.ssh/bastion_ed25519
Host internal
HostName 10.0.0.20
User admin
IdentityFile ~/.ssh/internal_ed25519
ProxyJump bastion
Приватный ключ от внутреннего сервера при этом не требуется копировать на bastion. Аутентификацию на конечном сервере выполняет локальный SSH-клиент.
Посмотреть итоговую конфигурацию, которую SSH применит для подключения, можно через:
ssh -G internal
Например, отдельно вывести основные параметры:
ssh -G internal | grep -Ei 'hostname|user|proxyjump|identityfile'
Если соединение не устанавливается, запускаем SSH с диагностическим выводом:
ssh -v internal
Для более подробной диагностики:
ssh -vvv internal
Так можно увидеть установление соединения через промежуточный узел, выбор ключей, проверку host key и этапы аутентификации.
ProxyJump можно использовать вместе с обычным port forwarding. Например, PostgreSQL работает на внутреннем сервере и слушает только локальный порт 5432:ssh -N -J user@203.0.113.10 \
-L 5433:127.0.0.1:5432 \
admin@10.0.0.20
После этого локально подключаемся к базе через порт
5433:psql -h 127.0.0.1 -p 5433 database
SSH-соединение пройдёт через bastion до внутреннего сервера, а перенаправление на
127.0.0.1:5432 будет выполнено уже со стороны конечного SSH-сервера.ProxyJump позволяет подключаться к серверам во внутренних сетях через bastion без ручного создания промежуточных SSH-сессий. Настройку можно вынести в ~/.ssh/config и использовать тот же маршрут для ssh, scp, sftp и SSH-туннелей.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍10❤9
This media is not supported in your browser
VIEW IN TELEGRAM
Здесь есть не только команды терминала с примерами, но и теория о процессах, памяти, правах, файловой системе и сети, а также темы вроде LVM, RAID, systemd, безопасности и контейнеров. Отдельный плюс — практика, задачи с решениями, диагностика типичных проблем и вопросы для подготовки к собеседованиям.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15👍12🔥5
Прокидываем TCP-порты через socat!
Бывает требуется опубликовать локальный TCP-сервис на другом порту или адресе, не изменяя конфигурацию приложения и не разворачивая отдельный reverse proxy. Для этого в линукс удобно использовать
Установим
Предположим, приложение принимает соединения только на loopback-адресе:
Проверим listener через
Для сервиса, привязанного к IPv4 loopback, вывод может выглядеть так:
Чтобы временно опубликовать сервис через порт
Проверим новый listener:
Если входящие соединения на
Адреса из документационных диапазонов в примерах необходимо заменить реальными адресами своей инфраструктуры. Параметр
Если публиковать порт на всех локальных IPv4-адресах не требуется, listener можно привязать к конкретному адресу:
В этом случае соединения принимаются только на
Для локального клиента это обычное соединение с
Ещё один полезный сценарий — публикация Unix domain socket через локальный TCP-порт. Предположим, приложение использует следующий сокет:
Свяжем его с
Если приложение обслуживает HTTP, проверить соединение можно через
Работает и обратное направление: Unix-сокет может передавать соединения в TCP:
Для диагностики достаточно добавить
Для постоянного проксирования предпочтительнее использовать штатную конфигурацию сервиса, reverse proxy, NAT или отдельный
🔥
🚪 Linux Ready | #практика
Бывает требуется опубликовать локальный TCP-сервис на другом порту или адресе, не изменяя конфигурацию приложения и не разворачивая отдельный reverse proxy. Для этого в линукс удобно использовать
socat — универсальный инструмент для двунаправленной передачи данных между сокетами.Установим
socat в Debian или Ubuntu:sudo apt update && sudo apt install socat -y
Предположим, приложение принимает соединения только на loopback-адресе:
127.0.0.1:8080
Проверим listener через
ss:ss -tlnp | grep ':8080'
Для сервиса, привязанного к IPv4 loopback, вывод может выглядеть так:
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:*
Чтобы временно опубликовать сервис через порт
9000, запускаем дополнительный listener:socat TCP-LISTEN:9000,reuseaddr,fork \
TCP:127.0.0.1:8080
socat принимает соединения на 9000/tcp и для каждого из них устанавливает TCP-соединение с 127.0.0.1:8080. Без bind IPv4-listener обычно привязывается к 0.0.0.0, поэтому порт становится доступен на IPv4-адресах хоста с учётом firewall и других сетевых ограничений.Проверим новый listener:
ss -tlnp | grep ':9000'
Если входящие соединения на
9000/tcp разрешены, сервис можно проверить через адрес сервера:curl http://203.0.113.10:9000
Адреса из документационных диапазонов в примерах необходимо заменить реальными адресами своей инфраструктуры. Параметр
fork создаёт дочерний процесс для каждого принятого соединения, а reuseaddr включает SO_REUSEADDR и упрощает повторную привязку адреса после перезапуска.Если публиковать порт на всех локальных IPv4-адресах не требуется, listener можно привязать к конкретному адресу:
socat TCP-LISTEN:9000,bind=192.0.2.10,reuseaddr,fork \
TCP:127.0.0.1:8080
В этом случае соединения принимаются только на
192.0.2.10. Параметр bind выполняет привязку к IP-адресу, а не непосредственно к сетевому интерфейсу.socat также может проксировать TCP-соединения на другой сервер. Например, локальный 5433/tcp можно направить на PostgreSQL внутри другой сети:socat TCP-LISTEN:5433,bind=127.0.0.1,reuseaddr,fork \
TCP:10.0.0.20:5432
Для локального клиента это обычное соединение с
127.0.0.1:5433, тогда как socat передаёт байтовый поток на 10.0.0.20:5432:psql -h 127.0.0.1 -p 5433 database
Ещё один полезный сценарий — публикация Unix domain socket через локальный TCP-порт. Предположим, приложение использует следующий сокет:
/run/myapp/app.sock
Свяжем его с
127.0.0.1:8080:socat TCP-LISTEN:8080,bind=127.0.0.1,reuseaddr,fork \
UNIX-CONNECT:/run/myapp/app.sock
Если приложение обслуживает HTTP, проверить соединение можно через
curl:curl http://127.0.0.1:8080
Работает и обратное направление: Unix-сокет может передавать соединения в TCP:
socat UNIX-LISTEN:/tmp/backend.sock,fork \
TCP:127.0.0.1:8080
Для диагностики достаточно добавить
-d -d, чтобы socat выводил информацию о создаваемых соединениях:socat -d -d \
TCP-LISTEN:9000,reuseaddr,fork \
TCP:127.0.0.1:8080
Для постоянного проксирования предпочтительнее использовать штатную конфигурацию сервиса, reverse proxy, NAT или отдельный
systemd-unit. socat полезен для диагностики, временной публикации сервисов и связывания TCP с Unix domain sockets без изменения конфигурации приложений.socat позволяет одной командой организовать простой транспортный прокси между TCP-портами, удалёнными адресами и Unix-сокетами — хороший инструмент для диагностики и тестирования сетевого взаимодействия.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥12❤4🤝2
Например,
${VAR:-default} использует значение по умолчанию, если переменная не задана, а ${VAR##pattern} и ${VAR%%pattern} позволяют удалять части строк прямо средствами Bash без дополнительных команд.На картинке — основные возможности Bash Parameter Expansion: установка значений по умолчанию, удаление префиксов и суффиксов, поиск и замена строк, извлечение подстрок, получение длины переменной и др.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍11❤3🤝3
При переносе резервных копий, архивов и образов дисков важно не только завершить передачу, но и убедиться, что полученный файл полностью совпадает с исходным. Связка rsync и SHA-256 позволяет возобновлять прерванное копирование и проверять данные перед дальнейшим использованием.
В этом посте:
• Создаём контрольную сумму исходного файла через sha256sum;
• Передаём большие файлы по SSH с возможностью продолжить прерванное копирование;
• Проверяем целостность полученных данных по SHA-256;
• Настраиваем проверку перед дальнейшей обработкой и используем rsync --dry-run.
Проверка контрольной суммы позволяет обнаружить изменения содержимого, которые нельзя выявить простым сравнением размеров файлов.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤9👍7🤝1