Bash Days | Linux | DevOps
23.2K subscribers
127 photos
22 videos
600 links
Авторский канал от действующего девопса

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

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

Курс: @tormozilla_bot

РКН: https://two.su/bashdays
Download Telegram
Большинство утилит/программ/скриптов и т.п. работают с временными файлами. Сначала они создают этот временный файл, пишут в него какие-то данные, а на выходе отдают готовый результат, будь то файл с выгрузкой либо что-то другое. А временный файл с которым производилась работа, естественно зачищается.

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

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

Этот случай я успешно отдебажил. Временный файл удалялся ДО того как стать файлом выгрузки. Почему? Потому что процесс удаления временного файла работал в отдельном потоке (thread) и удалял временный файл спустя 30 секунд.

А так как выгрузка с каждым годом становилась все больше, 30ти секунд стало мало. По итогу временный файл удалялся, а на выходе создавался пустой файл без каких либо данных. Естественно никакой обработки эксепшенов в бинарнике не было, вечный статус - завершено успешно! Файл же есть на выходе, значит успешно. Не поспоришь.

На такие ёбнутые случаи и нужен strace, чтобы хоть немного понять, что происходит.

Короче расчехляем нашу лабораторию и создаем скрипт. Бинарники мучить не будем, bash скрипта будет достаточно для понимания.

#!/bin/bash

echo $UID > /tmp/test.txt
unlink /tmp/test.txt

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

1. Записываем во временный файл /tmp/test.txt этот самый UID.
2. Удаляем временный файл.

Почему не rm а unlink? Потому что в моём случае это был именно unlink, который я нашел просматривая лог strace. Чем отличается unlink от rm, расскажу в следующих постах.

Так, подопытный скрипт есть. Запускаем так:

strace -yfe inject=unlink:error=EACCES ./script.sh

В этой конструкции мы говорим strace, чтобы проинжектил наш системный вызов unlink и передал ему насильно ошибку EACCES (Permission denied).

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

[pid 677954] unlink("/tmp/test.txt") = -1 EACCES (Permission denied) (INJECTED)

А сам временный файл останется на диске. Открываем его и смотрим, что же там внутри происходит.

По умолчанию инъекция будет сделана всем системным вызовам unlink, но есть возможность указать диапазон или конкретный индекс срабатывания. В этом посте можешь глянуть как узнать конкретный индекс (смотри строчку с when=4+).

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

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

Вот такие приключения порой случаются. Изучай. Хорошего дня!

tags: #linux #debug #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍113
Привет. Чем отличается команда rm от unlink? Давай смотреть. Обе эти команды умеют удалять, но в 99% ты используешь именно rm, потому что про unlink ты либо не слышал, либо тебе rm с головой хватает.

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

Как устроен процесс удаления файлов в linux, расскажу в следующих постах, сегодня у нас битва rm vs unlink.

У unlink есть всего лишь два ключа запуска help и version. Очень ограниченный инструмент, но чем инструмент проще, тем проще его синтаксис.

# unlink /tmp/hardlink
# unlink /tmp/file

Софтина очень молчаливая — как мужик. После удаления, она промолчит и ничего не выведет на экран.

Команда unlink использует системную команду unlink, в то время как команда rm использует системный вызов unlinkat. Оба системных вызова практически одинаковы.

Unlink не умеет работать с wildcard и globbing шаблонами. Так же ты не сможешь с помощью нее удалить каталог.

Короче одни минусы. А нахрена тогда она нужна? Ооо брат, сейчас расскажу. Запускаем команду и пытаемся насильно удалить файл которого нет в каталоге:

rm -f test.txt

И получаем - НИЧЕГО. То есть rm -f не вернуло ошибку, что файл отсутствует. А если сделать так:

unlink test.txt

получаем ошибку:

unlink: cannot unlink 'test.txt': No such file or directory

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

Короче с unlink можно гибче обрабатывать эксепшены в скриптах. А еще при использовании команды unlink отсутствует проверка безопасности. Она удалит файл, защищенный от записи. Хотя современная версия rm теперь тоже так умеет.

Оффтоп. Ну а если хочешь, чтобы твой файл никто не смог удалить, включая root, делай так:

chattr +i test.txt

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

Ключ i - сделает файл неизменяемым. Чтобы снять с файла этот аттрибут, в команде которая выше, замени знак «+» на «-».

Подытожим.
Для большинства повседневных задач конечно rm мастхев, но если ты пишешь софт для каких-то критичных систем, стоит не упускать из виду unlink.

Увидимся вечером.

tags: #linux #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍157
Писал писал я вам интересный пост на вечер, про очередные офигительные циркули gpt+terminal+bash, а потом понял, что эта сука денег через какое-то время хочет. Собственно, как и любая AI херовина, наивный. Короче заскамили мамонта. Форс мажор. Ну бывает… Раз не сложилось, давай так:

shopt -s cdspell

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

Далее делаем:

cd /va
cd /otp
cd /Home

Ха! Мы попадаем в каталог var/opt/home. Понял/а? Эта надстройка в терминале исправляет ошибки. Из коробки. Клёва!

Призываем древнейшее зло:

shopt -s autocd

Теперь вводим:

/etc/cron.d
~root
..
~-

1. Переход в директорию /etc/cron.d
2. Переход в хоумдир рута
3. Переход в папку на уровень выше
4. Переход в предыдущую директорию

Заметь что я не писал команду cd! Оно само…

Хз на сколько это вообще практично, но как видишь такое возможно. Изучай, может станешь фанатом этой фичи )

tags: #linux #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍95
Привет, о че нашел: пасхалка в текстовом редакторе nano.

1. Запусти редактор nano
2. Перейди на новую строку
3. Нажми CTRL+X, а затем Y
4. Назови файл: zzy и нажми Enter

Сочетание ^X + Y + zzy, вероятно, является ссылкой на xyzzy, чит-код, первоначально использовавшийся в Colossal Cave Adventure.

Получается из nano нельзя будет сохранить файл с названием zzy.

Там телега скоро запилит нормальное форматирование кода (в бете 4.10.4 уже работает). Наконец-то дождались, так что скоро все будет по красоте и без костылей. Я себе воткнул, уматно вообще!

tags:
#linux #трудовыебудни

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍75
Доброе утро господа и дамы… на картинки пока НЕ смотрим, все станет прозрачным чуть позже.

Создаем подопытный файл под рутом:

echo 'some text' > test.txt

Затариваем его:

tar -cf test.tar test.txt

Теперь открываем в hexdump:

hexdump -C test.tar

hexdump — инструмент который используется разработчиками и отладчиками приложений. Он может преобразовывать файлы и данные в приятный и читаемый формат.

Так, открыли. Смотри первую картинку к этому посту. Видишь root/root? Это имя владельца и имя группы файла. Так вот, при создании архива эти поля можно изменять.

Давай изменим:

tar --owner='bash' --group='days' -cf test.tar test.txt

Окей. Снова открываем в hexdump:

hexdump -C test.tar

Смотрим вторую картинку. На ней видим интересную ситуацию, пользователь изменился на bash, а группа на days. НО в системе у нас нет такого пользователя и группы. Хотя ожидаемый результат должен быть — user/group not found или что-то подобное.

-rw-r--r-- bash/days 10 2023-10-23 05:09 test.txt

Баг или фича? Причем если растарить такой файл (с ключом -p или без него), bash/days вернутся к root/root.

А теперь создадим с user/user (этот пользователь и группа есть в системе).

tar --owner='user' --group='user' -cf test.tar test.txt

Распаковываем:

tar -xf test.tar

И видим ситуацию, что у файла test.txt пользователь и группа user/user. Великолепно! Вот такое интересное поведение.

Из документации по тару по смещениям 108 и 116 находятся uid и gid.

char uid[8]; /* 108 */
char gid[8]; /* 116 */

Давай посмотрим смещение 108:

hexdump -Cs108 -n8 test.tar

получаем:

0000006c 30 30 30 31 37 35 30 00 |0001750.|00000074

Конвертим 0001750 в uid:

echo $(( 8#1750 ))

Опа, получили 1000, что соответствует пользователю user. А если этот трюк провернуть с bash/days то получим uid того пользователя, под которым тарили файл.

Короче как всегда везде есть свои нюансы и приколы, возможно обоснованные. Глубже копать не стал. Давай, увидимся вечерком!

tags: #linux #debug

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍115
Часто люди бездумно засовывают в крон запуск долгоиграющих скриптов и потом ловят кучу багов.

К примеру некий скрипт запускается в кроне каждый час. В какой-то момент, время выполнения скрипта начинает составлять 70 и более минут. Соответственно следующий джоб через 60 минут запустит еще одну копию этого скрипта. И понеслась 3.14зда по кочкам.

Я ловил у ребят подобные перлы, когда сервер просто раком встает, а в фоне крутятся 100500 процессов, которые насилуют mysql как портовую шлюху, вдоль и поперек.

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

Как такое реализовать? В бест-практиках это реализуется через lock файлы. Для удобства работы с lock файлами, в linux есть коробочный вариант утилиты, которая называется flock.

flock
— утилита, которая позволяет использовать лок-файл для предотвращения запуска копии процесса (вашего скрипта, крона или чего-то еще). Например, используя cron нужно быть уверенным, что предыдущий запуск вашего скрипта уже завершен.

Пишем обработчик:

#!/bin/bash

lock="/tmp/bashdays.lock"

[[ -f "${lock}" ]] || touch "${lock}"

(
flock -n -o -x ${fd_lock} || { echo 'Nice try' >&2; exit 0; }

sleep 100

) {fd_lock}<"${lock}"

Запускаем скрипт. Ничего полезного он не сделает, просто будет висеть 100 секунд. После того как ты запустил этот скрипт, в соседнем терминале попробуй запустить его же параллельно. В ответ ты получишь ожидаемое - Nice try.

Как только скрипт завершит работу, ты сможешь запустить его повторно.

Сначала создается lock файл если его нет, а далее начинается магия с дескрипторами и логикой.

Вместо sleep можно вставить запуск функции типа main() где и будет основная логика скрипта. Либо вообще через source (или точку) заинклудить свой скрипт. То есть можно сделать универсальную штуку, чтобы в каждый скрипт не пихать flock.

Делаешь один обработчик и передаешь ему параметром путь до скрипта + путь до lock файла. А обработчик через source подгружает уже полезную нагрузку.

Моё решение возможно не самое изящное, но рабочее. Изучай. Слышал что такое можно провернуть каким-то образом через сокеты, но особо не вникал. Если в комментах поделишься, будет очень полезно. Спасибо!

tags: #linux #bash #utils

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍145
А у нас тут снежок выпал, хоть что-то новенькое. А то эти приготовления к чертовой пятнице (которая будет идти до конца года) совсем уже вымотали. Привет.

Набрел вчера на консольную игрулю, называется Rick & Morty BASH Quest.

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

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

Сюжет прост - Саммер и Рик пропали! Нужно решить головоломки и найти их. Путешествуй по порталам, ищи подсказки, раскручивай истину.

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

Управление простое:

ls -
осмотреться на местности
cd - перемещение через порталы
cat - читать подсказки
pwd - если потерялся
man man - справка

🌐 Поиграть можешь тут

tags: #linux #games

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍731
Какой самый лучший способ на bash прочитать переменные из файла? Велосипедов я много повидал, но мастхев это конечно же закинуть все переменные в json файлик и без лишнего геморроя его использовать.

Создаем файл vars.json, закидываем в него переменные/константы или чо там у тебя в конфигах обычно содержится:

{
"login" : "user",
"password" : "12345678"
}

А в главном скрипте, который все это будет читать делаем так:

#!/bin/bash

config="vars.json"

login=$(jq -r '.login' < $config)
passwd=$(jq -r '.password' < $config)

echo $login
echo $passwd

Тут это - говорим в config как называется файл с переменными, а далее с помощью офигительной утилиты jq парсим конфиг без кучи говнокода и слёз.

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

jq - это мощный инструмент, позволяющий читать, фильтровать и писать JSON в bash.

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

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

tags: #linux #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍125
Ух ты сколько нас тут много стало. Привет, кого не видел. Давай поговорим про утилиту JC. Про нее почти никто не знает, значит самое время познакомиться.

JC это JSON конвертер на основе встроенных парсеров.

Если коротко, то с помощью jc можно конвертировать выхлоп различных утилит в json формат, а потом уже по-человечески извлекать данные.

Например, я хочу получить json от выхлопа iptables. Запускаю:

iptables -L | jc --iptables

И по итогу получаю годноту:

[{"chain":"INPUT","rules":[]},{"chain":"FORWARD","rules":[{"target":"DOCKER-USER","prot":"all","opt":null,"source":"anywhere","destination":"anywhere"},{"target":"DOCKER","prot":"all","opt":null,"source":"anywhere","destination":"anywhere"}..

Ну красота же. JC ограничена парсерами, но из коробки там прям на богатом все (около 50ти). Crontab, csv, ls, fstab, date, ping и т.п. Выбираешь парсер под нужную тебе задачу и получаешь готовый к работе массив данных.

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

JC так же можно использовать как модуль в python, так что, тут не только у башников праздник.

🐱 Страница проекта на github
🟢 Установка: apt/yum install jc

Лично я jc никогда не применял, но порой встречал в скриптах. Изучай, когда-нибудь обязательно пригодится.

tags: #linux #bash #utilites

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍126
Спокойно! Завтра устроим выходной по постам, на сегодня это последнее чтиво, обещаю. Внезапная интеграция вылезла, нужно перекрывать. Давай на сон грядущий поговорим про интерпретатор.

Все что работает на базе ядра linux, создание процесса происходит в два этапа. Процесс клонируется с помощью системных вызовов fork и clone. А копия процесса замещается кодом из указанного файла (exec). Детали пока опущу, речь про другое.

Ты всяко знаешь, что скрипт должен начинаться с символов #!. Эта штуковина называется SheBang.

Если дословно: SheBang = Она взрывает. Bang Bang, Feuer Frei! Как у Rammstein песенка, сразу фильм XXX на ум приходит. С лысым ЧСВ мужиком, а не про выгоревших чуваков позади дивана с одной миниатюрной мадмуазелью с дрочильного сайта.

В общем после #! нужно указать путь до интерпретатора, обычно мы с вами фигачим /bin/bash или питончик какой нибудь.

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

Если из командной строки запустить скрипт и системный вызов execve возвратит ошибку ENOEXEC

Процесс оболочки bash будет сам пытаться выполнить скрипт.

EXECVE()
= выполняет программу, заданную параметром filename. Программа должна быть или двоичным исполняемым файлом, или скриптом, начинающимся со строки вида #!.

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

В большинстве случаев ENOEXEC возвращается если первая строка не начинается с #! либо первая строка начинается с #! и в строке больше нет символов кроме пробелов и табуляций.

Так вот, это запустится:

#!
echo 'Have a nice bashdays'
exit

И это тоже запустится:

# super comment
echo 'Have a nice bashdays'
exit

Ну и это аналогично залетит в сакцесфул:

echo 'Have a nice bashdays'
exit

Так что не обязательно указывать нашу любимую конструкцию #!/bin/bash, интерпретатор тот еще жук и учитывает такие нюансы.

Если интересно поподробнее про это почитать, есть клевый мануал про всю эту суету с «ОнаВзрывает» или SheBang. Правда на английском, но с переводчиком вменяемо.

Исследуйте господа и дамы.

Всем котиков и доброй ночи 🚶‍♀️ 😎 ☠️ пойдука я дрыхнуть! А завтра наконец-то пятница и нет никаких ретроспектив и созвонов. Ура!

tags: #linux #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍84
Ура, я кажется выспался и почти отошел от дегустации чачи. В прошлую пятницу, коллега попросил помочь ему накидать промпт, ну знаешь же там все эти PS1/PS2/PS3. Короче приглашение командной строки типа: root@bashdays:~#.

А мне сука так лень было этим заниматься, опять документацию поднимать, вспоминать все эти ключи и параметры. Короче Фууу!

Сижу думаю, как послать в пешее эротическое и не обидеть особо. Долго думать не пришлось. Все уже придумано за нас.

После минуты гугления, нашел несколько хороших генераторов этой самой фиготы. Тыкаешь мышкой по кнопочкам и получаешь готовый промпт.

Чёрт, как правильно промпт или промт? Промт по моему какой-то переводчик раньше такой был, в общем не суть.

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

- Bash Prompt Generator
- Prompt Gen
- EZprompt

Там кстати телега обновление выпустила, всякие ништяки типа цитат, блоков кода и т.п. Буду теперь к постам это все применять. Не забудьте обновиться, чтобы у вас тут все красиво выглядело, а не как гавно.

Пойду дальше диван давить, да киношки смотреть. Наконец-то что-то похожее на выходной. Увидимся!

tags: #linux #services

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍152
Вчера посмотрел спокойной ночи малыши и отрубился, каково было моё удивление, что в 6 утра не пришлось вставать и отвозить ребенка в школу. Каникулы же! Эхх… Ладно, а у нас бесконечные рабочие будни.

Сегодня обсудим интересную команду в bash, которая называется enable. Эта команда включает или отключает встроенные команды оболочки. Чтобы проще было понять эту шляпу, разберем на практике.

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

type test

И видим выхлоп: test is a shell builtin. То есть используется команда test встроенная в оболочку. А не та что лежит на пути в test: /usr/bin/test. А как нам воспользоваться дисковой версией этой утилиты? А вот так:

enable -n test
type test

И мы получаем уже такое: test is /usr/bin/test. Получается мы сделали некое переключение. И по факту используем разные версии test.

Чтобы включить обратно встроенную команду test в оболочке, выполняем:

enable test

Так окей. Что еще можно с этим интересного сделать? А можно подгрузить расширения поставляемые с оболочкой. Некие плагины, экстеншены. Для этого эти экстеншены нужно установить (если у тебя их нет:

apt/yum install bash-builtins

Все это дело установится в папку /usr/lib/bash/. В ней будут всякие mkdir, rm, sleep и т.п. По сути это те же дисковые команды, только экстеншены для оболочки.

Для начала узнаем дисковую версию команды mkdir:

mkdir --version

Ага, есть: mkdir (GNU coreutils) 8.32

Теперь загружаем экстеншен в оболочку:

enable -f /usr/lib/bash/mkdir mkdir
mkdir --version

Хе! -bash: mkdir: --: invalid option

Теперь запускаем:

type mkdir

И получаем: mkdir is a shell builtin, то есть теперь mkdir используется не системный (дисковый), а тот что подгружен в оболочку bash.

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

Чтобы посмотреть что вообще подгружено в оболочку, воспользуйся командой:

lsof +fg -p $$

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

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

BASH_LOADABLES_PATH=/usr/lib/bash/
enable -f sleep sleep

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

Ну либо в ситуации когда ты случайно снес бинарники и нужно как-то админить и восстанавливать систему. В общем тут всё рассчитано на полный полет твоей фантазии.

Развлекайся )

tags: #linux #bash #utils

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍89
Если у тебя коряво отображаются посты, либо вообще не отображаются (нарисован грустный хуй смайлик) - обнови клиента телеграм и все взлетит.

Не пропустите новый пост, который выше 👆

Форматирование постов еще отлажу, пока лезут баги особенно с форматированием кода, но думаю все скоро пофиксят. Еще бы картинки разрешили посреди текста пихать, было бы вообще пушка!
👍38
Короче с новой версией телеги просто 3.14здец какой-то, буду пока нативно через старый клиент посты фигачить, без всех этих свистоперделок. Если статью про циркули не увидел, я позаботился о тебе и закинул ее в телеграф. Читай нативку прям из клиента, не должно всей это шляпы больше вылазить. Всем спасибо ребята за фидбеки!

https://telegra.ph/Enable-in-da-Bash-10-30
👍51
Подсмотрел тут у товарища интересную идею с итогами по постам за прошлый месяц. Типа ТОП лист самого интересного, что прям со свистом залетело в умы. Попробую и я такое провернуть. Поехали!

Больше всего просмотров:

- Про SheBang и интерпретатор (7350)
- Шаринг файлов с серверов в телеграм (6834)
- Утилита JC (6545)
- Форматер длинных строк (6469)
- Приколы с утилитой shopt (6379)
- Потрошим HereDoc (6300)
- Комбайн для архиваторов (6239)
- Лучший способ читать переменные из файла (6186)
- Как перелезть на VIM и не помереть (6089)

Больше всего пересылок:

- Изолируем пользователя в chroot (177)
- Компилируем bash скрипт в бинарный файл (136)
- Делаем красивые диалоговые окна (135)
- Игруля Rick & Morty Quest (132)
- Про flock и долгоиграющие скрипты (131)
- Фреймворк для тестирования bash скриптов (120)
- Уничтожаем процесс через порт с помощью Kill Port (113)

Больше всего комментариев и лайков:

- Strace или что запускает программа
- Про CTRL+D и завершение сессий
- Bash Prompt Generator
- Чем отличается rm от unlink

Ну и не забываем, что есть навигация по тэгам (в закрепленном сообщении). Да, очень хорошо выстреливает рубрика #debug. Надо наверное за прошлые месяцы тоже будет такую табличку сделать.

tags: #итогимесяца 10/23

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍123
О чо у меня есть, офигительная шпаргалина!

n.e. в колонке означает not existing (не существует)

Давай разберем:

command > file.txt

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

command >> file.txt

Поток вывода перенаправлен в файл, в терминале его не видно. Если файл существует, то новые данные добавятся в конец файла.

command 2> file.txt

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

command 2>> file.txt

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

command &> file.txt

Поток вывода и поток ошибок перенаправлены в файл, в терминале их не видно. Если файл уже существует, то он будет перезаписан.

command &>> file.txt

Поток вывода и поток ошибок перенаправлены в файл, в терминале их не видно. Если файл уже существует, то новые данные будут добавлены в конец файла.

command | tee file.txt

Поток вывода скопирован в файл, он виден в терминале. Если файл уже существует, то он перезапишется.

Команда tee в Linux считывает стандартный ввод и записывает его одновременно в стандартный вывод и в один или несколько подготовленных файлов.

command | tee -a file.txt

Поток вывода скопирован в файл, он виден в терминале. Если файл уже существует, то новые данные будут добавлены в конец файла.

(*)

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

command |& tee file.txt

В файл скопированы потоки вывода и ошибки, они видны в терминале. Если файл уже существует, то он перезапишется.

command |& tee -a file

Потоки вывода и ошибки скопированы в файл, в терминале их видно. Если файл уже существует, то новые данные будут добавлены в конец файла.

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

tags:
#linux #sheets #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18321
Всем привет и доброе утро. Ребята вчера попросили анонсировать наш чатик. Собственно анонсирую — у нас есть чатик. В нём можешь смело задавать свои вопросы или рассказать всем про своё рабочее место, ну или как ты ушатал продакшен.

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

Ну а если устал от всех этих технических штук, велком в наши юморные айти каналы «Псина» и «Гарден».
👍421
Пока я готовлю разжеванный пост про стандартные потоки ввода-вывода, закину тебе еще одну игрулю для изучения оболочки через геймификацию.

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

Называется эта поделка GameShell.

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

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

GameShell запустится на любой операционке Linux/macOS.

Устанавливать так:

sudo apt install gettext man-db procps psmisc nano tree bsdmainutils x11-apps wget

$ wget https://github.com/phyver/GameShell/releases/download/latest/gameshell.sh
$ bash gameshell.sh

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

🐱 Страница проекта на github

tags: #linux #games

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍87
Привет. Я часто использую set -xve для отладки bash скриптов. Вообще это мастхев фича именно на момент, когда ты что-то создаешь. Ведь не всегда логика может работать правильно (в моих случаях так и есть), а с set -xve, ты вовремя можешь увидеть все значения переменных и т.п. не используя мусорные конструкции в своих поделках типа echo «Error in function xxx».

Конструкцию с set я обычно вставляю в shebang либо после, отдельным сетом:

#!/bin/bash -xve

set -xve

<script body>

Ключики команды set:

x =
Выводим команды и их аргументы по мере их выполнения.
v = Выводить строки ввода командной строки по мере их считывания.
e = Немедленный выход, если команда завершается с ненулевым статусом.

Окей. Как-то дебажил один большой и сложный скрипт на овердофига строк. В какой-то момент скрипт завершался с ошибкой. В режиме отладки set -xve я видел, где он упал. Но мне хотелось знать — а на какой строке это произошло? Номера строк увы не выводятся, а по поиску и визуально искать - ну такое себе.

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

Изменяем PS4
и добавляем вывод номера строки во включенный дебаг режим:

#!/bin/bash -xve

PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

bar=10
echo ${bar}
echo $((6 + 6))

После выполнения скрипта, получаем нумерацию строк:

bar=10
+(./script.sh:6): foo=10
echo ${bar}
+(./script.sh:7): echo 10
10
echo $((6 + 6))
+(./script.sh:8): echo 12
4

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

Ну а чтобы добавить визуального оргазма, экспортируем PS4 так:

PS4='\033[0;33m+(${BASH_SOURCE}:${LINENO}):\033[0m ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

Происходит подкрашивание запускаемых строчек.

С помощью PS4 мы можем отладить shell-скрипт, задав при его выполнении set -x, что позволяет выводить каждую команду, а затем ее результаты. Перед каждой командой ставится знак +, эту строку подсказки "+" можно изменить, определив переменную PS4.

Берите на вооружение. Хорошего дебага и с пятницей. Берегите себя!

tags: #linux #bash #debug

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2211