Bash Days | Linux | DevOps
23.3K subscribers
147 photos
25 videos
667 links
Авторский канал от действующего девопса

Самобытно про разработку, devops, linux, скрипты, сисадминство, техдирство и за айтишную жизу.

Автор: Роман Шубин
Реклама: @maxgrue

MAX: https://max.ru/bashdays

Курс: @tormozilla_bot
Блог: https://bashdays.ru
Download Telegram
Грустно признавать, но сегодня под вечер будем ковыряться в кишочках и дебажить аномалию. Но оно того стоит!

Выполняем команду:

echo Shs | base64 -d  
Jase64: invalid input


И наблюдаем аномалию в названии утилиты: Jase64.

Из команды понятно, что утилита base64 при декодировании обнаружила ошибку в данных. Ошибка — не корректная длина закодированного текста (invalid input).

Но чо за херня с Jase64? Новая попа-группа Юры Шильникова-Томатного? Должно же быть Base64?

Если что-то пошло попесде, нам поможет «страус». Расчехляем strace.


Давай посмотрим что и куда пишет base64. Перенаправляем стандартные потоки вывода и ошибки в устройство /dev/null. Дополнительно говорим «страусу», чтобы выводил системные вызовы write.

Запускаем кишку:

с запущенной кишкой, обычно к практологу

LC_ALL=C strace -Yqqqyfe write -P /dev/null --signal=none bash -c 'echo Shs | base64 -d &>/dev/null'


Кратенько по ключам:

LC_ALL = страхуемся
Y = чекаем вызовы ввода-вывода
qqq = меньше мусора
y = показываем пути к файлам
f = чекаем дочерние процессы
e = выбираем вызовы write
P = ограничение трассировки
signals = не следим за сигналами

После запуска получаем:

[<base64>] write(1</dev/null>, "J\33", 2) = 2
[<base64>] write(2</dev/null>, "base64: ", 8) = 8
[<base64>] write(2</dev/null>, "invalid input", 13) = 13
[<base64>] write(2</dev/null>, "\n", 1) = 1


Уже поинтереснее. Разбираем.

- В первой строке происходит запись части декодированного текста в стандартный вывод (дескриптор 1).

- В следующих двух строках, в стандартный поток ошибок пишется имя утилиты и ошибка (дескриптор 2).

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

Теперь снова смотрим первую строку и видим что системный вызов write пишет букву «J» и какой-то магический символ 33.

✔️ «Страус» по умолчанию выводит числовые значения непечатных символов в восьмеричной системе счисления. То есть 033 будет соответствовать символу ESC в кодировке ASCII.

И чо? А то, что для драйвера терминала, этот символ означает начало управляемой последовательности. Вот это поворот!

Скучная теория

Драйвер терминала это код, который распознает управляющие последовательности и интерпретирует их в действия. Например, перемещает курсор.

В моем случае, драйвер это эмулятор терминала (Terminal). А еще есть код в пространстве ядра, который реализует специальные устройства. И этот код может модифицировать данные проходящие через эту линию связи.

Схема терминала:

Bash write stdout -> /dev/pts/number Kernel_Space <- /dev/ptmx Terminal read

Terminal write -> /dev/ptmx Kernel_Space <- /dev/pts/number Bash read


Bash read это чтение команды, или сочетания клавиш например для редактирования строки.

Возвращаемся к Jase64

Для начала исключаем пространство ядра (Kernel_Space) и проводим проверку данных, которые поступили на устройство читаемое эмулятором терминала.

Видим что на устройстве эмулятора Terminal, данные пришли без искажений. Подозреваемым остается драйвер терминала.

write(30</dev/ptmx>, "\33[200~echo Shs | base64 -d \33[201"..., 33) = 33


Как это 👆 получить, я рассказал утром в этом посте.


И происходит следующее. Эмулятор терминала получив символ «J» отображает его, но потом натыкается на специальный символ ESC начало управляющей последовательности и слово base64.

Символ «b» распознаётся как часть управляющей последовательности и этот символ не отображается.

Многие терминалы не имеют никаких действий связанных с данной последовательностью «ESCb» и она просто отбрасывается.

Ниже пару примеров, когда часть последующего ввода распознаётся как завершение управляющей последовательности.

echo -ne 'J\033' ; sleep 3 ; echo base64 >&2  
echo -ne 'J\033[64' ; sleep 3 ; echo bashdays >&2


Вот такие вот приколы, вот такие вот кишочки. Нельзя просто так взять и насыпать в терминал всё что тебе захочется.

Если после каких-то действий, ты начал замечать аномалии, выполни команду reset и всё встанет на свои места.

Хорошая статья: The TTY demystified.

И да, всем отличных предстоящих выходных, берегите себя ❤️

Не забываем подписываться на пиздатые тулзы.


tags: #linux #bash #debug

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
109
Привет. В пятницу пришел клиент с вопросом — а как вы нам пайплайны со сломанным докером починили после блокировки в РФ?

Вопрос был с явным «подъебом». Почему я так решил? Сейчас объясню.

Как большинство решило проблему? Правильно, прочитали хайповую тему с хуёкером и проксяки ну и в моменте пофиксили, включая продакшены.

Я тоже хотел провернуть нечто подобное, сделать за 5 минут, затрекать 8 часов, получить денежку. Гениальный план! НО, за годы появилось «чутьё».

Поэтому решено было сделать всё правильно — перенести официальные образы в инфраструктуру клиента и поправить пайплайны. По итогу накидал bash скрипт, забрал 200 образов, залил. Делов на полчаса.

Ты спросишь, а как обновлять образы? А никак, все образы зафиксированы на определенные версии, глупо использовать latest. На моей практике, не раз новая версия образа ломала совместимости.

✔️ Вернемся к вопросу клиента.

На вопрос я честно и прозрачно ответил. Клиент одобрительно покивал головой и сказал:

Респект и уважуха. Я думал вы как и все, воспользовались инструкцией с хабра, а это категорически недопустимо по нашим политикам безопасности. Спасибо за работу, я никогда не сомневался в ваших компетенциях. Оплатим по двойному тарифу. Сделано быстро и профессионально.


Собственно в этом и скрывался «подъебон». Если бы я сделал как ВСЕ, получается, мне плевать на клиента, на его проекты и бизнес. Хотя отчасти так и есть, чо лукавить 😲

Естественно мне пришлось бы всё переделывать, не говоря уже про доверие и дальнейшее сотрудничество.

Всегда думай своей кабиной. Пофиксишь быстро, все обрадуются, получишь денежку, но через неделю будут яростно ебать в жопу. Когда инфраструктура встанет раком из-за какого-нибудь встроенного майнера в образ или MITM атаки.

В крайнем случае можешь поднять свою доверенную, личную проксюшку и через неё забирать образы.


Дело конечно твоё, с советами не лезу. Личные наблюдения.

Есть такая прекрасная поговорка — мой ишак, хочу еду, хочу ебу!

Так, что если ты CTO, задай вопрос своим девопсам и админам, как они решили эту проблему с образами. Будет прекрасный повод распилить их премию и устроить оргию на ретроспективе.

Короче нормально делай, нормально будет! Хорошей рабочий недели и береги себя!

tags: #рабочиебудни

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
226
Здрасти. Наш товарищ Tagd Tagd написал для канала еще одну статейку, ловите. Предыдущая была тут. В остальном оставляйте свой фидбек в комментах.

👇👇👇

spr.sh


Решил написать справочник. Получился консольный гугл для бедных. Консольный справочник для поиска инфы по тегам.

В В ТЭГАХ КОНФИГА ИСПОЛЬЗОВАТЬ СИМВОЛ ПОДЧЕРКИВАНИЯ "_" НЕЖЕЛАТЕЛЬНО.

Вся инфа хранится в конфигурационном файле в виде:

# spb director ivanov ivan petrovich may
Иванов Иван Петрович
tel 123456789 director@mail.ru
ats 12587
loip 10.10.18.07
birth 22.05.1956
https://ya.ru


# bash if then else fi
declare -i $COND=0
if [[ "$COND" -eq 1 ]];then
echo "FALSE"
else
echo "TRUE"
fi


Набираем spr.sh regexp mail и получаем все записи, содержащие эти оба тэга. Порядок не важен.

При поиске можно использовать "_" для уточнения.

spr.sh bcd   = вхождение bcd (найдет bcd, abcd, bcde, abcde)
spr.sh _bcd = начинается на bcd (найдет _bcd, _bcde)
spr.sh bcd_ = заканчивается на bcd (найдет bcd, abcd)
spr.sh _bcd_ = строго bcd (найдет bcd)


Обращаю внимание, поиск только по ВХОЖДЕНИЮ тэгов, но не комментов.

В общем, можно быстро получить список телефонов любого филиала, отдела, именинников в этом месяце... Или забить примеры кода и получить справочник для студентов/админов по конструкциям bash sed awk grep regexp в одном флаконе.

Если нужно что-то поправить: spr.sh edit и конфигурашка открывается в редакторе. Этот режим можно использовать для поиска средствами редактора по всему конфигу, включая комменты.

✔️ Описание скрипта:

EDITOR - в каком редакторе открывать конфиг (vim mcedit)
CONF - имя конфига получаем из текущего имени скрипта.
$# -eq 0 - если нет параметров - выводим help.
${0##*/} - bash-аналог basename
eval "$(which $EDITOR) $CONF" ищем редактор и открываем конфиг


Далее awk.

Передавать $* (параметры скрипта) внутрь через переменную не стал, сразу встроил в однострочник (да-да. это однострочник)

BEGIN{split("'"$*"'",s," ")} до начала чтения файла разбиваем тэги по разделителю " " и записываем в массив s. обработка строк файла: ($0 ~ /^#/)

Для строк, начинающихся с символа # (тэг-строка)

k0=$0 - сохраняем строку тэгов на время поиска.
gsub(/^#/, "# ") - добавляем пробел после #


Теперь поле №1

for(i=2;i<=NF;i++){$i="_" $i "_"} обрамляем тэги "_" для более удобного поиска.

p=1 и проверяем в цикле наличие КАЖДОГО тэга во всей строке.

($0 !~ s[i]) Если искомого тэга в строке нет, p=0 и выход из цикла.

$0=k0 - восстанавливаем строку тэгов.

Если p=1 - (флаг печати) выводим строки.

Обращаю внимание, изменение переменной p только в тэг-строках

Использовать для хранения учетных данных нежелательно. Для этого есть KeePassXC и аналоги.

#!/bin/bash
declare -r EDITOR=nano
declare -r CONF=${0%.*}.conf
declare -r SCR=${0##*/}
if [[ $# -eq 0 ]];then
echo "Search by tag1 && tag2 && ... in $CONF"
echo "Usage: $SCR tag1 [tag2 ...[tagN]]"
echo "Example:"
echo "$SCR bcd ~> (seek bcd, abcd, bcde, abcde)"
echo "$SCR _bcd ~> (seek bcd, bcde)"
echo "$SCR bcd_ ~> (seek bcd, abcd)"
echo "$SCR _bcd_ ~> (seek bcd)"
echo
echo "To edit conf: $SCR edit"
exit
fi
if [[ "$1" == "edit" ]];then
eval "$(which $EDITOR) $CONF"
exit
fi
awk 'BEGIN{split("'"$*"'",s," ")}
{if($0 ~ /^#/){
k0=$0
gsub(/^#/, "# ")
for(i=2;i<=NF;i++){
$i="_" $i "_"}
p=1
for(i in s){
if($0 !~ s[i]){
p=0
break}}
$0=k0}
if(p){print}
}' "$CONF"


tags: #bash

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
54
Что делать если хочется поебаться с Bash, но мамка отключила тебе интернет?

Выход есть!

Я обычно всю эту трихомудию с синтаксисами, ключами и т.п. в голове не таскаю. Серой оперативки вроде хватает, но мозг ленивая штука.

Поэтому если что-то нужно подсмотреть, сразу в гугол. А в последнее время в gpt накидываю.

Зачем хранить фильмы на dvd дисках и mp3 скачивать, когда есть стриминговые сервисы.


Когда мы жили в пещерах и подтирались зайцами, таких ништяков у нас не было. А был какой-нибудь blackcat linux и ты. ВСЁ! Ну и фидошка временами.

Ответ на свой вопрос в фидошке иногда приходилось ждать неделями и то не факт.

Книги? Неа, максимум ZX-ревью и прочие нечитабельные клоны. А хотелось Башить!

Оставалось изучать исходники чужих скриптов, которые шли из коробки в дистрибутиве linux.

Ну и естественно man, в который особо никто не въезжал, потому что с английским были небольшие проблемы — заебешься по словарику переводить, а уроки английского успешно прогуляны.

И что самое интересное, это было гораздо эффективнее, чем в нынешние времена. Информация записывалась на подкорку. Как скилл — умение ездить на велосипеде.

А сейчас — прочитал книгу, вроде всё понятно, грейд — крепкий мидл. Прошла неделя, ты отупел и уже ничего не помнишь. Информация записалась в голову, но потом могз — блядь, говнище какое-то, нужно срочно это забыть, есть же интернет!

✔️ Короче, к чему это я.

Если пишешь на каком-то языке и нужны примеры конкретных функций или команд. Далеко ходить не надо, всё нужное хранится на твоём диске.

Давай заглянем на диск и посмотрим на примере Shell скриптов, которые валяются в /usr/bin, /usr/sbin, /bin, /sbin.

file /{,usr/}*bin/* | grep -Po '^.+?(?=:\s+.+?shell script)' | xargs grep -wl -m1 'getopts'


Команда идет по каталогам и ищет нужное слово, в нашем случае ищем пример работы с функцией «getops». По ключам расписывать не буду, интернет у тебя явно пока еще есть.

По итогу отработки этой кишки, получаем пути и имена файлов, где эта функция используется. Открываем и смотрим как оно применяется на практике.

Даже если оказался в глубокой жопе тайге без интернета, один на один с Linux, выход есть! В своё время люди на папирусе код писали. Было бы желание.

Пользуйтесь!

tags: #bash #linux

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
150
Сегодня заумных простыней не будет, тем не менее следующая кишка на bash тебе пригодится.

strace -o "| grep -Eo '/home/[^\"]+' >&2" -zfe '/^open' mc


✔️ Делает она следующее

При запуске программы (в моём случае это mc), в терминал вываливается список всех файлов, которые программа открывает в домашнем каталоге.

Штука очень полезная для дебага. Когда не знаешь к каким файлам программа обращается, а очень хочется.

Эту команду можно усовершенствовать, поменяв пути и добавив например вызовы write. Тут уже от ситуации зависит.

При первом запуске mc я получил такой список:

/home/user/.config/mc/ini
/home/user/.config/mc/ini
/home/user/.config/mc/panels.ini.E4M2O2
/home/user/.config/mc/ini
/home/user/.config/mc/ini
/home/user/.config/mc/ini~
/home/user/.config/mc/ini
/home/user/.bash_history


Если в твоём сознании живёт стройный и прекрасный мир программ, и ты человек с утончённой душевной организацией, воздержись от использования этого инструмента, лучше сходи на pornhub.


Пользуйтесь!

tags: #bash #linux #debug

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
142
Делать если честно совсем ничего не хочется, вчера к примеру закинули охуенную задачу — чтобы внести цифровой продукт в реестр отечественных ПО, нужно написать подробнейшую документацию к проекту.

Чтобы специалисты «миницифер», смогли локально у себя его развернуть и всё проверить.

Ну это ладно, вся соль в том, что нужно это подробно и в мельчайших подробностях расписать (без матов).

От начала создания сервера (консольные команды, пайплайны, апстримы, фаерволы и т.п.) и заканчивая — а теперь открываем браузер и видим главную страницу нашего приложения. Отдать код ансибла — не канает. Заебись да?

Короче пезда какая-то, чувствую себя как ребенок, который ненавидит делать домашку. Ладно, лирика. Поехали по сегодняшней теме.

✔️ Как узнать какие сигналы слушает процесс

Требуется проверить поймает ли запущенный процесс сигнал, проигнорирует или заблокирует его. Короче нужен список сигналов для конкретного приложения.

➡️ Про сигналы писал тут и тут


В Linux ты можешь найти PID процесса, а затем посмотреть:

cat /proc/$PID/status


В выхлопе будут строки описывающие какие сигналы

SigBlk - заблокированы
SigIgn - проигнорированы
SigCgt - перехвачены

Для примера беру PID=1, получаю такое:

SigBlk: 0000000000000000
SigIgn: fffffffe57f0d8fc
SigCgt: 00000000280b2603


Роман ты заебал! Опять какие-то шифры нечитабельные.

Давай разберемся что это значит.

Все эти числа справа, являются битовой маской. Если преобразовать это из шестнадцатеричного в двоичный, то каждый 1 бит представляет собой пойманный сигнал, считая справа налево, начиная с 1.

Итак, интерпретируя строку SigCgt, видим, что мой init процесс улавливает следующие сигналы:

00000000280b2603 ==> 101000000010110010011000000011


На телефонах вся эта поебота выглядит очень стрёмно, поэтому смотрим картинку к этому посту 👆


Как сопоставить числовые сигналы с именем? Я выполнил команду:

kill -l


И получил список всех сигналов от 1-31, а дальше уже дело техники.

И помним, что мы не можем заблокировать сигнал, если программа не готова к его перехвату. Если сигнал не был пойман, происходит действие по умолчанию, обычно это — завершение процесса.

Нахера всё это нужно? Ну если ты рядовой потребитель, то конечно оно тебе и не нужно. А если ты «автомеханик», то извините, хош не хош, а как оно внутри работает знать обязан.

Вот те скрипт, который покажет какие сигналы прослушивает программа. Да, скрипт преобразует криптошифры в нормальные имена сигналов. Избавляю вас от еботни, как говорится все для вас мои дорогие подписчики 🙃

#!/bin/bash

set -e

grep -m3 -P '^Sig(?:Blk|Ign|Cgt):' "/proc/$1/status" | while read field value
do
bits=$(printf 'ibase=16; obase=2; %X\n' '0x'$value | bc)
sigs=()
i=0
while [[ $bits ]]
do
((++i))
[[ ${bits:$((${#bits} - 1))} -eq 1 ]] && sigs+=($i)
bits=${bits::-1}
done
(( ${#sigs[*]} )) && sigs=( $(kill -l ${sigs[*]}) )
echo $field ${sigs[*]}
done
exit


При запуске нужно указать PID процесса: script.sh <pid>

Вроде всё. Если есть чо добавить, велком в комменты. Ну и всех с пятницей, хороших предстоящих выходных, берегите себя!

Пользуйтесь!

tags: #bash #linux #debug

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
127
Прочитал недавно в полезняшках — про кириллические символы, ну и пошел экспериментировать, но немного в другом векторе. Раскроем так сказать тему сисек.

Сегодня займемся поиском шрифтов в Linux, которые поддерживают русскую букву «А». И посмотрим какие из них могут использоваться совместно с утилитой convert.

Чо еще в субботу делать 🍷 Завтра пауза с постами, приведу к нам сюда еще единомышленников.

Для начала нужно узнать какие вообще шрифты в системе поддерживают этот символ. Для этого используем утилиту «fc-list» из пакета «fontconfig».

Для поиска возьмем код символа «0410» в utf-8. Он соответствует кириллической букве «А».

Также можно указать диапазон :charset=0410-044f (охватывает все заглавные и строчные буквы русского алфавита от А до Я) ну или язык :lang=ru.

✔️ Поехали! Выводим все шрифты, которые поддерживают кодовую точку «0410».

fc-list ':charset=0410' --format '%{file}\n'


Есть нюанс. В список могут попасть шрифты, которые будут содержать кодовые точки, но у них не будет изображений символов.

Далее сопоставляем найденные шрифты, с теми которые поддерживает утилита convert.

Утилита convert является частью пакета программного обеспечения ImageMagick. Это мощный инструмент для создания, редактирования, преобразования и отображения растровых изображений.


fc-list ':charset=0410' --format '%{file}\n' | grep -wof - <(convert -list font)


Чо тут происходит. Мы отдаём через pipe результаты отработки команды fc-list на стандартный ввод grep.

w = шаблон, соответствует слову
o = выводим только совпадения, а не всю строку
f = файл строки в качестве шаблона поиска

Конструкция <(convert -list font) это подстановка процессов. Доступна в системах, поддерживающих именованные каналы (FIFO) или метод именования открытых файлов через /dev/fd.

Она имеет вид: <(список) или >(список)

Запускается процесс список и его входной или выходной поток связывается с именованным каналом FIFO или одним из файлов в /dev/fd.

Имя этого файла передается в качестве аргумента текущей команде как результат подстановки.

Если использовать >(список), запись в файл будет давать входные данные процессу список.

Если используется <(список), файл, переданный в качестве аргумента, необходимо читать для получения результатов работы процесса список.

Получается в качестве аргумента команда grep получит файл. Содержимым которого будет результат работы команды convert -list font.

Проверяем:

echo <(convert -list font)
cat <(convert -list font)


В итоге получаем нужный список шрифтов.

  Font: URWGothic-Book
family: URW Gothic
style: Normal
stretch: Normal
weight: 400
glyphs: URWGothic-Book.otf
Font: URWGothic-BookOblique
family: URW Gothic
style: Oblique
stretch: Normal
weight: 400
glyphs: URWGothic-BookOblique.otf


Ну а дальше можем заряжать все это в bash скрипт и гордится, какие мы с тобой охуенные.

Для примера давай сгенерим кучу изображений с русской буквой «А» используя найденные шрифты.

#!/bin/bash  

code=0410
char=$(printf '%b' '\U'$code)
fc-list ':charset='$code --format '%{file}\n' |\
grep -wof - <(convert -list font) | while read line
do
name=${line##*/}
name=${name%.*}
convert -font "$line" -pointsize 48 label:"$char" ./${name}.png
done


После запуска скрипта, в каталоге появится портянка файлов с изображениями, учти этот момент, чтобы не засрать себе поапочку. Лучше сразу в tmp это делай.

У меня всё, не смею тебя больше отвлекать. Изучай. Увидимся!

tags: #bash #linux

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
70
И снова понедельник и снова на работу. Сегодня про оптимизацию и управляющие последовательности. Бест-практики, трувей ёпта!

Если в своих скриптах или программах ты часто используешь одинаковые управляющие последовательности, имеет смысл сохранить результаты работы утилиты tput в переменную.

Скучная теория

tput используется для управления терминалом и выполнения различных задач, связанных с его настройкой и управлением.

Управляющие последовательности — это специальные последовательности символов, используемые для управления поведением терминала. Они позволяют изменять цвета текста, перемещать курсор, очищать экран и выполнять другие действия, не изменяя сам текст.


✔️ Практика

Чтобы не усложнять, рассмотрим пример на основе clear. Эта команда очищает экран.

clear=$(tput clear)


Помещаем в переменную очистку экрана. Теперь проверяем:

printf '%s' $clear  
echo -n $clear


После выполнения одной из этих команд, экран терминала будет очищен.

А почему просто не выполнить команду clear без этих вонючих tput? Потому, что это самый простой пример, чтобы ты въехал в суть.

Получается мы не плодим в своих скриптах кучу tput clear а используем оптимизированный вариант с переменной.

Чем больше параметров в tput, тем больше треша в скриптах. Проще же один раз закинуть в переменную эту кишку и не маяться хуйнёй.

Посмотреть управляющую последовательно ты можешь так:

echo ${clear@Q}


На экран выведется:

$'\E[H\E[2J\E[3J'


Конструкция: ${clear@Q} это использование параметра расширения в Bash, который отображает значение переменной clear в форме, пригодной для использования в качестве строки в программном коде. Это означает, что специальные символы будут экранированы.

Начиная с версии 4.4 в Bash, значение parameter заключаются в одинарные кавычки.

${parameter@Q}


Экранирование помогает избежать интерпретации специальных символов терминалом и позволяет безопасно выводить последовательности на экран.


Пример одной строкой:

tput cup 20 60 | { read -r BASHDAYS; echo ${BASHDAYS@Q}; }


1. Генерируем управляющую последовательность для перемещения курсора терминала на 20 строку и колонку 60.
2. Передаем полученную строку по пайпу.
3. Читаем строку и присваиваем ее переменной BASHDAYS.
4. Выводим значение переменной BASHDAYS.

По итогу получаем такое:

$'\E[21;61H'


Еще вариант:

tput cup 1 10 | cat -v ; echo


Результат сам посмотришь если интересно.

Для многих это тема не новая, но я частенько наблюдаю в скриптах избыточное применение этих управляющих последовательностей.

Короче пихай это говнище в переменную и будет заебись!

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

Давай краба, увидимся!

tags: #bash #linux

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
64
Привет. Завтра оказывается внеплановый выходной, придется вечером идти за пивом и досматривать «Задача трёх тел» и «Сёгуна».

И раз такие пироги, расскажу тебе про очередную хуйню, с помощью которой я в данный момент делаю себе ой как больно.

Все посты для этого канала я пишу в Obsidian, это не только текстовый редактор, но и вообще комбайн для сбора и структурирования информации.

Короче если ищешь куда складировать знания, рекомендую присмотреться к Obsidian, работает на любой операционке, включая мобилки.

И еще это основной инструмент адептов Zetelkasten.

Цеттелькастен (нем. Zettelkasten, буквальный перевод «ящики для заметок») — система ведения заметок и управления личными знаниями, используемая в исследованиях и учёбе.


Звучит это правда как — Флюгегехаймен!

Теперь про боли. В последни год я редко пишу код, совсем забросил свой любимый vim и успешно забыл все комбинации клавиш.

Ситуация конечно интересная — тратишь кучу времени на изучение комбинаций в vim, доводишь их до инстинктов и мышечной памяти. Но спустя месяц, все эти скиллы куда-то бесследно испаряются.

Походу как у бодибилдиров, накачал за год банки, на месяц сделал паузу и превратился снова в дрища. Ну пиздец же.

А чтобы не просрать эти скиллы, нужно ежедневно их применять. А как их применять, если нет необходимости?

Просто так дрочить вприсядку тоже не хочется, хочется чем-то полезным заниматься и не деградировать.

В общем в Obsidian есть нативная поддержка vim. Я конечно знатно прихуел, но воодушевился.

То есть я могу теперь писать для вас посты в комфортной для себя среде и не проёбывать скиллы по виму.

Это же прекрасно! 🤙

Правда я растерял всю свою прыть и поэтому приходится заново затачивать свои зажившие пальцы под аккорды вима.

Мыши кололись, плакали, но продолжали есть кактус…

Ты наверное предложишь мне писать посты сразу в виме, идея хорошая, но от Obsidian я тащусь не меньше чем от вима. Все же это немного разные инструменты.

Вот те ссылка на Obsidian чтоб не искать

Так что, теперь я совмещаю приятное с полезным. Люблю изобретать.

Может и тебя этот пост натолкнет на какие-то правильные мысли. И ты скрестишь своего бульдога с носорогом.

Кстати когда я в Obsidian включил режим VIM, он мне выдал интересный попапчик, в котором до включения режима, предложил пройти небольшой квест. Прям повеселило! 👇

tags: #рабочиебудни

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
113
Как говорится никогда не строй планы заранее. Вчера я успешно задрых и проебал момент с чаркой пива и сериальчиками. Ну хоть выспался, 12 часов сна пошли на пользу.

А сегодня я принес тебе Puter. Это операционка прям в браузере. Даже терминал есть, но урезанный.

Фишка этой операционки — ты можешь ее в докере поднять у себя и радоваться, прекрасно подходит для всяких малинок если иксы ставить прям впадлу. Ну и куча софта предустановлено, открывай и пиши код до посинения.

Вся эта кухня в оупенсорсе на гитхабе.

В демо версии есть хром браузер. Через него можно побегать по сайтам не светя свою жопку с айпишником.

Айпишники кстати там разные попадаются, сейчас мне показывает — Пиздастан Редмонд.

Ну ты понял, как этим можно воспользоваться 😲

Кстати отлично запускается порнохабина, даже ЗВУК есть!


Короче я принес, а ты уже сам смотри, мож где сгодится в хозяйстве. Увидимся!

tags: #services

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
92
Здрасти. Такое ощущение, что сегодня понедельник.

Вчера коллега принёс вопрос — часто встречаю в настройках терминала, выбор каких-то xterm, vt100, linux, rxvt и т.п.

Чо это такое и как влияет на потенцию?

Вопрос на самом деле хороший, но его в приличном обществе предпочитают не задавать. Потому что мало кто про это вообще задумывался. По итогу эту настройку игнорируют и оставляют по умолчанию.

Давай разберемся, что же это за зверь и какой вариант выбрать правильно.

TL;DR Выбирай xterm-256color

Все эти vt100, xterm и др. всё это типы терминалов. vt100 был разработан в конце 1970х, а xterm более современная версия. Но все равно все они уёбищные.

Поэтому каждый из нас выбирает что-то мастхевное, Tilix, Quake, iTerm и т.п. Их можно заточить под свои хотелки и максимально кастомизировать.

Давай посмотрим чем vt100 отличается от xterm.

Добавляем в .bashrc экспорт и перезаходим:

export TERM=vt100


Теперь выполняем:

echo -e "\e[31mHello Bashdays\e[0m"


И видим что управляющие символы не сработали. А если экспортировать xterm-256color, то строка Hello Bashdays будет красной.

А теперь попробуй в vt100 запустить midnight commander и что-то в нем поделать. Ты будешь приятно удивлён — всё сломалось. Мышка не работает, UTF-8 не работает, F10 не работает, нихуя не работает.

Отличий на самом деле много, смысла нет все их перечислять. Используй современные решения и не лепи горбатого.

А в современном мире вообще используется vt100?

Конечно! Например, доисторические программы на каких-нибудь всратых заводах, которые заточены именно под этот вид терминала.

Либо какое-то специальное оборудование, которому не требуются свистоперделки современных терминалов, а важна лишь скорость, ясность и низкие системные требования.

В общем пусть прошлое остается в прошлом. А чтобы писька не отвалилась, выбирай — xterm-256color!

👇 UPD by Igor Shilov 👇

Это таблицы конвертации ESC-последовательностей , если очень кратко. В одном случае такая последовательность провоцирует эмулятор терминала что-то сделать (типа цвет выводимого текста поменять) в другом - отображается буковками как есть.


tags: #linux

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
1032
Как говорится — у хорошего айтишника и бычий хуй веревка!

Привет. Сегодня про find и временные метки.

У утилиты find есть ключ -newer. Тест (-newer) возвращает истину, если метка X новее метки Y.

Формат теста такой:

-newerXY


Y — Указывает временную метку образца.
X — Указывает временную метку искомых файлов.


Временные метки:

с — время изменения
m — время модификации
a — время последнего доступа
t — буквальное время, а не имя файла (только Y)
B — время создание файла (поддерживается не везде)


Поддерживаемые форматы (t):

Вот несколько из них, которые можно получить с помощью утилиты date.

date --rfc-3339=ns  
date --rfc-2822
date +'@%s.%N'
TZ=UTC0 date +'%Y-%m-%d %H:%M:%S'
date +'%Y-%m-%d %H:%M:%S %z'
LC_ALL=C TZ=UTC0 date


Также date умеет отнимать/прибавлять даты.

date -d'- 1 hours'


Более подробно можешь почитать в гнутой доке. Или заглянуть командой: info coreutils date

Теперь давай поищем файлы в домашнем каталоге у которых время модификации, менялось с заданной даты. Минус 2 часа от текущего времени.

find ~/ -newermt "$(date --rfc-2822 -d '- 2 hours')"


Ага, получаем ожидаемый список. Ок, теперь создадим файл bashdays.txt, у которого время модификации будет -2 часа от текущего времени.

touch -mt $(date '+%Y%m%d%H%M.%S' -d '-2 hours' ) bashdays.txt


Проверяем:

stat bashdays.txt


Смотрим поле Modify, ага все верно, время -2 часа от текущего времени.

Снова запускаем поиск файлов, у которых время модификации свежее времени модификации файла bashdays.txt

find ~/ -newermm bashdays.txt


Выводим дополнительную информацию со временем модификации найденных файлов:

find ~/ -newermm bashdays.txt -printf '%t\n'


Допускается задавать разные временные метки искомых файлов и образца. Поиск файлов у которых время модификации новее времени изменения файла bashdays.txt

find ~/ -newermc bashdays.txt -printf '%t\n'


Чтобы узнать, при каких условиях изменяются временные метки. Можете поизучать man-страницы к системному вызову stat.

Где это можно применить? Ну например, для зачистки старых бэкапов, если предпочитаешь использовать для этого самописные скрипты. На самом деле дофига где применить можно, всё зависит от фантазии и потребностей.

Завтра выходной строим, в воскресение вернусь. Хороших предстоящих выходных, береги себя!

tags: #linux #bash

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
84
Сегодня без прелюдий. Давай через утилиту ps узнаем время, когда был запущен процесс.

Делается это довольно просто. Для начала запустим подопытного. У меня будет гуёвая убунта. Запускаю firefox.

/usr/bin/firefox


Можешь с ярлыка на рабочем столе его заранить. А если нет иксов, подставь cron или какой-нибудь свой скрипт который крутится в фоне.

Дальше открываем терминал и фапаем:

ps --no-headers -C firefox -o lstart


В ответ видим строку: Sun Jun 16 05:54:24 2024

Это и есть та самая временнáя метка, когда был запущен процесс. В моем случае firefox.

Аналогично можно узнать метку любой запущенной программы или процесса.

Формат поля lstart универсальный и его понимает тест(-newer) из предыдущего поста про find.

Давай поищем файлы в домашнем каталоге, которые были модифицированы после запуска firefox.

find ~/ -newermt "$(ps --no-headers -C firefox -o lstart)"


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

Некоторые версии утилиты ps могут создать головняк с поиском процесса по имени. Но эта ситуация легко решается с помощью других утилит для поиска PIDов.

Например, с помощью такой кишки:

find ~/ -newermt "$(ps --no-headers -p $(pgrep firefox) -o lstart)"


Думаю концепт ты понял, а дальше можешь самостоятельно пойти и разгрести какой-нибудь /proc/pid/stat или /proc/uptime.

Пользуйтесь!

⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️

А еще подписывайся на наши полезняшки и заходи попиздеть в чатик.

Поржать тут:
@devopsina и @devopsgarden

tags: #linux #bash

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
1161
Если угораешь по оффлайн утилитам и швейцарским ножам, то эта мастхэвная штука как раз для тебя.

Называется DevToys. Работает под всеми операционками, натыкиваешь мышкой, получаешь результат. Есть даж портативная версия, чтобы не засирать систему мусором.

DevToys включает в себя более 30 полезных утилит.

Я обычно в онлайне подобными штуками пользуюсь, типа там json проверить, сконвертировать или наглядно кронтаб соорудить.

Эта тулза прям зашла именно как оффлайн. В моей тайге не всегда есть интернет и онлайн сервисы теряют свою актуальность, а работать как-то надо.

Кстати кто презирает гуёвость, есть и cli версия. А еще можно свои модули написать и расширять функционал до бесконечности. Короче полный фарш. Советую потыкать.

Качнуть с гитхаба ➡️ DevToys

И еще есть в официальном Microsoft Store, тыкнул Download и она у тебя.

Состав, тыкай на спойлер

- Converters
| - JSON <> YAML
| - Timestamp
| - Number Base
| - CRON Parser
- Encoders / Decoders
| - JWT
| - HTML
| - URL
| - Base64 Text & Image
| - GZip
- Formatters
| - JSON
| - SQL
| - XML
- Generators
| - Hash (MD5, SHA1, SHA256, SHA512)
| - UUID 1 and 4
| - Lorem Ipsum
| - Checksum
- Text
| - Inspector & Case Converter
| - Regex Tester
| - Text Comparer
| - XML Validator
| - Markdown Preview
- Graphic
| - Color Blindness Simulator
| - Color Picker & Contrast
| - PNG / JPEG Compressor
| - Image Converter
... and more are coming!

tags: #utilites

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
1121
Не переношу жару, черт его знает как в детстве мы сидели во дворе и пили водку на солнце в +45 градусов, сейчас бы я так не смог.

Сегодня будем проводить ректальное тестировать переменной PATH с помощью кишки.

( set -f; IFS=':'; for i in ${PATH:?'хуй с маслом'};do [[ -r "$i" && -d "$i/." ]] || echo "$i";done )


Эта кишка проверяет элементы в переменной PATH. И выводит на экран которые не существуют, или к которым нет доступа на чтение.

Давай разберем каждый элемент отдельно:

set -f


Отключает функцию pathname expansion (или globbing). Это предотвращает интерпретацию символов *, ? и [] как шаблонов имен файлов.

IFS=':'


Устанавливает разделитель полей (Internal Field Separator, IFS) на двоеточие «:». Это необходимо для правильного разбора переменной PATH, где пути разделены двоеточием.

for i in ${PATH:?'хуй с маслом'}


Запускает цикл for, который перебирает каждый элемент переменной PATH. Выражение ${PATH:?'empty path'} проверяет, что переменная PATH не пустая; если она пустая, выводится сообщение «хуй с маслом» и выполнение прерывается.

do [[ -r "$i" && -d "$i/." ]] || echo "$i"; done


Внутри цикла проверяется каждый элемент «i» из PATH.

[[ -r "$i" && -d "$i/." ]]


Проверяет, существует ли каталог (-d "$i/.") и доступен ли он для чтения (-r "$i").

|| echo "$i"


Если каталог не существует или недоступен для чтения, то выводится значение «i» (путь).

Думаю более менее понятно. Если видишь огромную кишку, разбивай её на части и тогда с ней проще будет разобраться.

Это как в тайм-менеджмент, что-то там блядь про делёжку слона на маленькие кусочки.


В общем суть такая — если переменная PATH не установлена или пустая, команда завершится и будет выдано сообщение «хуй с маслом».

Поля переменной PATH отображаются на экран, если не соответствуют минимальным требованиям, или являются нулевыми. Bash будет искать в текущей директории.

man bash → PARAMETERS → Shell Variables → PATH

PATH The search path for commands.  It is a colon-separated list of directories in which the shell looks for commands (see COMMAND EXECUTION below).  A zero-length (null) directory name in the value of PATH indicates the current directory.  A null directory name may appear as two adjacent colons, or as an initial or trailing colon.  The default path is  system-dependent,  and is set by the administrator who installs bash.  A common value is `/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin'


Минимальные требования.

Каждый элемент пути должен иметь бит исполнения. Последний элемент должен быть каталогом и обладать разрешением на чтение, исполнение.

Для запуска программы достаточно, чтоб исполняемый файл программы имел бит исполнения и все каталоги в пути имели бит исполнения, чтения (не требуется если указываете полный путь до исполняемого файла).

У меня например после запуска кишки, выдало:

/snap/bin


Пошел смотреть и точно, в переменной PATH этот каталог указан, а физически его нет на диске.

Для исследования путей удобно использовать команду namei.

namei -m /etc

f: /etc
drwxr-xr-x /
drwxr-xr-x etc


Тему про PATH поднимал раннее в этом посте.


Ну а так вроде всё, изучай!

tags: #bash #linux

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
101
Здравствуйте товарищи. Ну чо, как оно?

Поехали еBash’ить. Сегодня разберем интересную задачку, которую я подкидываю на собесы. Задача со звездочкой.

Суть задачи: нужно вывести строки в окно терминала и пронумеровать их используя только один вызов sed. Аналогично выводу команды nl.

То есть должно получиться такое:

printf '%s\n' {a..d} | nl


1 a
2 b
3 c
4 d


Только это нужно сделать с помощью одного вызова sed.

Обычно кто берется ее решать, спустя какое-то время говорят — Роман, иди нахуй, это сделать невозможно!

Так говорят бедолаги, которым либо лень что-то делать, либо писька еще не отросла. Всё возможно, было бы желание.

Короче поехали решать. Давай попробуем сразу с sed несколько вариантов.

printf '%s\n' {a..d} | sed '='  
printf '%s\n' {a..d} | sed -n 'p;='
printf '%s\n' {a..d} | sed -n '=;p'


Ну чет да… ожидаемый результат совсем не ожидаемый.

Дело в том, что когда sed встречает команду «=», он тут же пишет текущий номер строки с завершающим символом «\n» или «\0». То есть номер и строка разделены «\n» или «\0».

Поэтому в примерах по sed для решения этой задачи, используют два вызова.

printf '%s\n' {a..d} | sed '=' | sed 'N;s/\n/ /'


Вот так всё корректно отработает, но задачу мы не решили, условия другие. Нам можно использовать лишь один sed.

Чо будем делать? Думать ёпта!

Для начала надо посмотреть, а что мы имеем и на что можем повлиять.

Утилита sed пишет строки. Куда она их пишет? Вот и решение…

Вставляем в начало каждой строки, управляющую последовательность. Которая переместит курсор на предыдущую строку и установит его например в 3 колонку.

printf '%s\n' {a..d} | sed '=;s/^/\x1b[1A\x1b[3G/'


Получаем ожидаемый результат:

1 a
2 b
3 c
4 d


Поздравляю! Задача решена с помощью всего лишь одного вызова sed.

Если очевидные решения не приносят результата, всегда можно воспользоваться неочевидными. Благо таких неочевидных решений бесконечное множество.


Изучай. Всех с пятницей и хороших предстоящих выходных. Береги себя!

tags: #bash #linux

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
1131
Зрасти. Сегодня замутим простую проверку корректности формата файла. Для этого воспользуемся утилитой sed.

Вводные

Есть файл с последовательностью символов 1, 2, 3, 4, 5. Каждая цифра с новой строки. Эти символы могут располагаться в любой позиции строки. Строка может содержать другие символы отличные от символов заданной последовательности.

Пример такого файла:

1  
2
3
4
a1
b2
3c
4d


Теперь нужно, чтобы при проверке такого файла, программа прерывалась и выводила номер строки, которая нарушает формат. Если файл содержит допустимую последовательность или пустой, то — молчим.

Создаем скрипт check

#!/usr/bin/sed -nf

$bE ; /1/!bE ; n
$bE ; /2/!bE ; n
$bE ; /3/!bE ; n
/4/b

:E = ; q


Необычно? Необычно! Это скрипт на языке Sed. Давай Разберем, что тут происходит.

$bE = Если находимся на последней строке переход к метке «E».

/1/!bE ; n = Если текущая строка не содержит 1, переход к метке «E». В противном случае переходим к следующей строке.

… аналогично для 2 и 3

/4/b = Если текущая строка содержит 4, перейти в конец скрипта.

:E = ; q = метка «E» печатает текущую строку и завершает выполнение.

Погнали чекать кейсы. Не забудь на check впиздярить +x.

printf '%s\n' {1..3} | ./check
printf '%s\n' {1..4} | ./check
printf '%s\n' {1..4} {1..5} | ./check
printf '%s\n' {1..4} {1..4} | ./check
printf '%s\n' a{1..4} b{1..4} | ./check
printf '%s\n' a{1..4} b{1..3} | ./check


1. Выводится 3 номер строки
2. Пусто. Файл валиден.
3. Выводится 9 номер строки
4. Пусто. Файл валиден.
5. Пусто. Файл валиден.
6. Выводится 7 номер строки

Вместо перехода на метку можно просто выходить и возвращать нужное значение с помощью команды «q» которая в GNU версии принимает аргумент.


Чтиво: адресация, команды, шаблоны

tags: #bash #linux

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
48
Забавная хуита. Виндовз что с тобой?

Короче если создать текстовый файл с содержимым «This content is no longer available.» и сохранить его, винда начинает жестко угорать.

Мол, вы пиздец хакер и только что создали вирус под названием Trojan:Win32/Casdet!rfn. Касдет-пиздет.

Trojan:Win32/Casdet!rfn – это вредоносная программа, относящаяся к категории удаленного доступа (RAT). Она позволяет злоумышленникам получить контроль над вашим компьютером, красть ваши данные и устанавливать другие вредоносные программы.


Прикольно. Что-то из оперы EICAR

X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


По-видимому, это коллизия хэшей. Потому что только Windows Defender его детектит, вот репорт с вирус-тотал.

tags: #мозготрах

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
74
Ну и пекло, по ощущениям +60 и комары. Сегодня на изи, KPI нулевой.

Узнаем имя и путь последнего файла/каталога. Иногда нужно отработать подобный кейс, чтобы произвести какие-то манипуляции над последним файлом в каталоге.

ls -t ~/backups/* | head -1


Выдаст полный путь до файла/каталога. В примере папка с бекапами. Чтобы не ебстись и городить кишку с find, у ls есть для этого ключик для сортировки.

Ну и с помощью head, забираем имя последнего файла/каталога.

Всё, пойду дальше плавиться…

tags: #bash #linux

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
1091
Со шрамами приходит сила

И снова здрасти. Хуй знает очевидная эта штука для тебя или нет, но я все равно ее подсвечу.

Предположим у тебя есть какой-то проект описанный в docker-compose.yml. Вся эта чача раскатывается через пайплайны gitlab на продакшен.

Из того что я постоянно вижу — После сборки проекта, все собранные файлы копируются на продакшен с помощью rsync, scp или подобных утилит, ну и ранится все это дело через ssh.

Например:

script 
- билд хуилд
- rsync -avz --delete ./ user@$prod:/var/www`
- ssh user@$prod "docker compose up -d"


1. Что-то там собралось
2. Файлы синканулись с продом
3. Запустилось если смогло

Хуита! Всё делается изящнее. Ща покажу.

stage: deploy
image:
name: docker/compose
script:
    - docker-compose -H "ssh://root@$prod" down --remove-orphans
    - docker-compose -H "ssh://root@$prod" pull
    - docker-compose -H "ssh://root@$prod" up -d


Используем мощности docker-compose, не привлекаем никакие rsync, scp и т.п. А сразу нативно запускаем на проде наш docker-compose.yml файл.

Никаких лишних файлов не копируется, никаких утилит, минималистичное. Я примеры сократил, но суть ты поймешь. Не обязательно тащить на прод какие-то ямеэльки.

В штыки не воспринимай, способ с rsync и т.п. вполне годный. Но делюсь, тем, чем пользуюсь сам. У меня телеграм боты так деплоятся.

Изучай. Не отвлекаю! Если хоть одному из вас пригодится, это уже хорошо!

tags: #devops

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
208