Про офигительные циркули. Порой бывает устанавливаешь какую нибудь софтину на linux, а впридачу с ней идет огромный example конфиг. Этим конфигом можно пользоваться по дефолту, либо тонко настраивать. Например, конфиг от php.ini весит 80 килобайт. И больше половины в этом конфиге - комментарии и шляпа.
А хочется сделать из этого конфига простенький шаблон например для ansible, но без лишнего мусора. Чтобы было основное, что позволит софтине вообще запуститься (пути, логи, сокеты и т.п.). Руками выкашивать 60-70 килобайт, то еще занятие.
Но что если сделать свой собственный маленький парсер? Который выкосит все ненужное и оставит необходимый минимум. Да, прям на bash! Погнали зажигать!
Для примера будем работать с тем же файлом php.ini и приведем его в юзер-френдли вид.
Накидываем скрипт:
В моем случае комментарии в файле идут после «;» символа. Обращаем внимание, что второй параметр передаем в кавычках. Если передать напрямую, то оболочка bash не поймёт что от нее хотят и выпадет в panic.
Разбираем скрипт:
Присваиваем переменной sep, символ, который передали вторым параметром $2. У меня это символ «;».
Далее идет цикл, который построчно читает файл php.ini переданный в первом параметре $1 при запуске скрипта. Тут универсально, можешь любой файл передать, скрипт его сам схавает как нужно.
IFS= разделяет строку с использованием символа в качестве значения
Ну и логика цикла:
Если первый символ равен символу «;», который уже лежит в переменной sep ИЛИ первый символ равен пустой строке, ТО передаем управление команде continue, которая проигнорирует запись в output файл. И так по кругу, пока не закончится файл.
Команда continue пропускает оставшиеся команды внутри тела цикла для текущей итерации и передает управление программой к следующей итерации цикла.
Символ || означает = ИЛИ
ВО ВСЕХ ДРУГИХ СЛУЧАЯХ, происходит запись в output файл, в котором будут содержаться только необходимые для работы параметры.
На выходе получится 2х килобайтный файл php.ini.tpl, без комментариев и прочего шлака. Чистый как слеза.
80 килобайт vs 2 килобайта! Ха! Разница ощутима, теперь можно сделать шаблончик для ansible/puppet/chef.
В своем скрипте я использую простые регулярные выражения. ДА! В bash это можно делать через символы «=~».
$sep = символ с помощью которого комментируют строки
.* = оставшийся кусок строки
А можно еще другим способом определять начинается ли строка с определенного символа. Но конкретно с разделителями «;»/«#» это будет работать не корректно.
пезда , выводится соответствующее сообщение. Регулярок тут нет, чисто «*» правит балом.
Такие дела. И без применения всяких sed/бред/винегрет. Нативно, на bash, даже с регулярками научились взаимодействовать, а регулярки развязывают на многое руки. В пределах разумного, не нужно brainfuck создавать.
Brainfuck — один из эзотерических языков программирования, придуман Урбаном Мюллером
Я рассмотрел ситуацию с созданием шаблона, но этот метод парсинга применим вообще под любые задачи, где нужно определить является ли первый символ тем, который тебе нужен. Бери на вооружение.
Завтра сделаем паузу, а в четверг и в пятницу еще немного поэкспериментируем. Давай! Пока-пока!
tags: #bash
—
💩 @bashdays
А хочется сделать из этого конфига простенький шаблон например для ansible, но без лишнего мусора. Чтобы было основное, что позволит софтине вообще запуститься (пути, логи, сокеты и т.п.). Руками выкашивать 60-70 килобайт, то еще занятие.
Но что если сделать свой собственный маленький парсер? Который выкосит все ненужное и оставит необходимый минимум. Да, прям на bash! Погнали зажигать!
Для примера будем работать с тем же файлом php.ini и приведем его в юзер-френдли вид.
Накидываем скрипт:
#!/bin/bashЗапускаем так:
sep=$2
while IFS= read -r var
do
[[ $var =~ ^$sep.* ]] || [[ ! $var =~ ' ' ]] && continue
echo "$var" >> $1.tpl
done < $1
./script.sh php.ini ";"Передаем 2 параметра. Первый = имя файла-конфига, который будем читать и парсить. Второй = символ, которым комментируются строки в этом файле.
В моем случае комментарии в файле идут после «;» символа. Обращаем внимание, что второй параметр передаем в кавычках. Если передать напрямую, то оболочка bash не поймёт что от нее хотят и выпадет в panic.
Разбираем скрипт:
Присваиваем переменной sep, символ, который передали вторым параметром $2. У меня это символ «;».
Далее идет цикл, который построчно читает файл php.ini переданный в первом параметре $1 при запуске скрипта. Тут универсально, можешь любой файл передать, скрипт его сам схавает как нужно.
IFS= разделяет строку с использованием символа в качестве значения
Ну и логика цикла:
Если первый символ равен символу «;», который уже лежит в переменной sep ИЛИ первый символ равен пустой строке, ТО передаем управление команде continue, которая проигнорирует запись в output файл. И так по кругу, пока не закончится файл.
Команда continue пропускает оставшиеся команды внутри тела цикла для текущей итерации и передает управление программой к следующей итерации цикла.
Символ || означает = ИЛИ
ВО ВСЕХ ДРУГИХ СЛУЧАЯХ, происходит запись в output файл, в котором будут содержаться только необходимые для работы параметры.
На выходе получится 2х килобайтный файл php.ini.tpl, без комментариев и прочего шлака. Чистый как слеза.
80 килобайт vs 2 килобайта! Ха! Разница ощутима, теперь можно сделать шаблончик для ansible/puppet/chef.
В своем скрипте я использую простые регулярные выражения. ДА! В bash это можно делать через символы «=~».
$var =~ ^$sep.*^ = соответствует началу текстовой строки
$sep = символ с помощью которого комментируют строки
.* = оставшийся кусок строки
А можно еще другим способом определять начинается ли строка с определенного символа. Но конкретно с разделителями «;»/«#» это будет работать не корректно.
[[ $var = Y* ]] && echo "String start with Y"В примере выше, происходит проверка, является ли первый символ в строке символом «Y» и если да, то
Такие дела. И без применения всяких sed/бред/винегрет. Нативно, на bash, даже с регулярками научились взаимодействовать, а регулярки развязывают на многое руки. В пределах разумного, не нужно brainfuck создавать.
Brainfuck — один из эзотерических языков программирования, придуман Урбаном Мюллером
Я рассмотрел ситуацию с созданием шаблона, но этот метод парсинга применим вообще под любые задачи, где нужно определить является ли первый символ тем, который тебе нужен. Бери на вооружение.
Завтра сделаем паузу, а в четверг и в пятницу еще немного поэкспериментируем. Давай! Пока-пока!
tags: #bash
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍121
👍75
В Linux есть масса утилит, для поиска файлов. К примеру всем известный монструозный find, который умеет даже тапочки приносить.
Но что, если мне нужно просто найти какой-то файл? Использовать find для такой простой задачи, это явно стрельба из пушки по воробьям. Для таких задач, как моя, есть более изящные решения.
И это решение, утилита locate.
Утилита locate используется для поиска файлов, расположенных на машине пользователя или на сервере. Фактически она выполняет ту же работу, что и команда find, однако, ведёт поиск в собственной базе данных.
Ключевая фраза здесь - в собственной базе данных. То есть применяя утилиту locate, поиск файлов будет осуществляться не по файловой системе, как это делает find. А будет использоваться собственная база данных. Коротая позволяет искать файлы со скоростью света.
Обновление базы данных locate происходит автоматически, как правило, раз в сутки. Либо можно запустить руками командой
Давай теперь потыкаем, запускай:
Ищем файлы, которые оканчиваются на «txt»
Ключ -с = вывести общее количество найденных файлов
Полезли в кишки, заводим strace.
Переходим в папку cd /tmp и создаем подопытный файл:
Так, я нахожусь в папке tmp и у меня создан файл
Мы вызываем внешнюю команду locate, но вызываем мы ее из интерпретатора bash. Вернее её вызывает сам интерпретатор. И это накладывает свои нюансы. В нашем случае этот нюанс «Подстановка имен файлов», то есть Globbing.
Сейчас будет сложно для понимания, но чуть ниже я разжую на человеческий.
Во времена UNIX V6, существовала программа /etc/glob, которая могла раскрывать шаблоны подстановки. Очень скоро она стала встроенной функцией командной оболочки.
Но что же случилось то в итоге, почему ничего не нашлось? А произошло следующее: после того, как интерпретатор обнаружил символ «*», который является спецсимволом и соответствует любой строке, интерпретатор попытался сделать подстановку Globbing и ему это удалось.
И при вызове команды locate она получила в качестве аргументов, результат этих подстановок. Давай посмотрим наглядно что произошло. Запускаем:
execve() выполняет программу, заданную параметром filename
Возвращаемся к выводу от strace и видим что locate получила в качестве аргумента
Вот лишь по этому на экран ничего не вывелось, когда я запустил
Если ты это усвоил, то уже не наступишь на грабли. Да и strace снова немного затронули, можешь применять для дебага и смотреть что происходит внутри, после вызова той или иной команды.
Поигрались и хватит. Пошли дальше работу работать. Всех был рад видеть, пока-пока!
tags: #bash #strace #debug
—
💩 @bashdays
Но что, если мне нужно просто найти какой-то файл? Использовать find для такой простой задачи, это явно стрельба из пушки по воробьям. Для таких задач, как моя, есть более изящные решения.
И это решение, утилита locate.
Утилита locate используется для поиска файлов, расположенных на машине пользователя или на сервере. Фактически она выполняет ту же работу, что и команда find, однако, ведёт поиск в собственной базе данных.
Ключевая фраза здесь - в собственной базе данных. То есть применяя утилиту locate, поиск файлов будет осуществляться не по файловой системе, как это делает find. А будет использоваться собственная база данных. Коротая позволяет искать файлы со скоростью света.
Обновление базы данных locate происходит автоматически, как правило, раз в сутки. Либо можно запустить руками командой
updatedb.Давай теперь потыкаем, запускай:
locate txtИщем все файлы, имена которых содержат «txt». Опа, меньше чем за секунду команда нашла все подходящие файлы, которые можно было найти. А если сделать это через find, то это у меня это заняло 18 секунд. Разница очень ощутимая.
Ищем файлы, которые оканчиваются на «txt»
locate '*txt'А теперь давай посчитаем общее количество файлов, которые нашлись
locate -ic '*txt'Ключ -i = режим регистронезависимости
Ключ -с = вывести общее количество найденных файлов
Полезли в кишки, заводим strace.
Переходим в папку cd /tmp и создаем подопытный файл:
> hello.txt
Знал же что пустой файл можно создать через символ «>»? Если нет, то теперь знаешь.Так, я нахожусь в папке tmp и у меня создан файл
hello.txt запускаю:locate *txtОпа, ничего нет, как так? Мы же уже запускали ранее это, чтобы найти все файлы, которые заканчиваются на txt. Что случилось?
Мы вызываем внешнюю команду locate, но вызываем мы ее из интерпретатора bash. Вернее её вызывает сам интерпретатор. И это накладывает свои нюансы. В нашем случае этот нюанс «Подстановка имен файлов», то есть Globbing.
Сейчас будет сложно для понимания, но чуть ниже я разжую на человеческий.
Во времена UNIX V6, существовала программа /etc/glob, которая могла раскрывать шаблоны подстановки. Очень скоро она стала встроенной функцией командной оболочки.
Но что же случилось то в итоге, почему ничего не нашлось? А произошло следующее: после того, как интерпретатор обнаружил символ «*», который является спецсимволом и соответствует любой строке, интерпретатор попытался сделать подстановку Globbing и ему это удалось.
И при вызове команды locate она получила в качестве аргументов, результат этих подстановок. Давай посмотрим наглядно что произошло. Запускаем:
strace -e execve locate *txtНа выходе получаем:
execve("/usr/bin/locate", ["locate", "hello.txt"], 0x7ffe242252d8 /* 27 vars */) = 0
Опция «e» и аргумент «execve» сообщают strace, что я хочу отслеживать только системные вызовы «execve».execve() выполняет программу, заданную параметром filename
Возвращаемся к выводу от strace и видим что locate получила в качестве аргумента
hello.txt
И теперь locate будет искать файлы именно по этому шаблону, а не по тому, что мы с тобой ожидали, когда писали «*txt».Вот лишь по этому на экран ничего не вывелось, когда я запустил
locate *txt
А чтобы этого не происходило всегда используй quoting (кавычки) и будешь получать ожидаемый результат.locate '*txt'Механизм подстановки имен файлов (Globbing) на самом деле удобен, просто нужно использовать его по назначению.
Если ты это усвоил, то уже не наступишь на грабли. Да и strace снова немного затронули, можешь применять для дебага и смотреть что происходит внутри, после вызова той или иной команды.
Поигрались и хватит. Пошли дальше работу работать. Всех был рад видеть, пока-пока!
tags: #bash #strace #debug
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍157 2
Здарова! У меня на машине имеется пачка всяких alias’ов для продуктивной работы. К примеру есть такой
Я привязал команду cat к нужной мне утилите. В данном случае это batcat. Про нее я рассказывал в предыдущих постах.
Все работает отлично, но что мне делать когда требуется деактивировать этот alias и воспользоваться чистой командой cat?
Ты скажешь - дак залезь в файл ~/.bashrc/.zshrc да закомментируй всю эту срамоту. Справедливо! Но это какое-то топоровое решение.
Есть несколько вариантов как это осуществить нативно и красиво. Ща покажу.
Посмотреть все прописанные alias, можно через одноименную команду alias, выведется полный список.
Первый вариант
Перед командой ставим символ «\»:
Второй вариант
Помещаем команду в кавычки, хоть в двойные хоть в одинарные:
Третий вариант
Капитанский вариант с указанием полного пути к команде:
Чтобы узнать полный путь к команде, воспользуйся одним из этих способов, они очень часто встречаются в bash скриптах, я приводил пример в этом посте.
С помощью команды command
Пятый вариант
Этот вариант пожалуй более глобальный, который отключает алиасы в текущем сеансе. Не удаляет, а именно «анлиасит» в текущей сессии.
А чтобы вообще дропнуть все алиасы в текущей сессии, запускай такое:
Я использую первый вариант, он достаточно быстрый и менее трудозатратный. Ну а если что-то дебажу, то применяют пятый вариант. Для чистоты экспериментов, чтобы на грабли не наступить там где не нужно.
С пятницей коллеги! Хороших тебе предстоящих выходных и береги себя! Пойду дальше мемы для Псины рисовать, забегай если скучно.
Спасибо всем проголосовавшим в этом посте, большинство ЗА, так что в ближайшее время прикручу комменты. Но терзают меня пока сомнения, в общем решим этот вопрос. Увидимся!
tags: #bash #linux
—
💩 @bashdays
alias cat='batcat’. Я привязал команду cat к нужной мне утилите. В данном случае это batcat. Про нее я рассказывал в предыдущих постах.
Все работает отлично, но что мне делать когда требуется деактивировать этот alias и воспользоваться чистой командой cat?
Ты скажешь - дак залезь в файл ~/.bashrc/.zshrc да закомментируй всю эту срамоту. Справедливо! Но это какое-то топоровое решение.
Есть несколько вариантов как это осуществить нативно и красиво. Ща покажу.
Посмотреть все прописанные alias, можно через одноименную команду alias, выведется полный список.
Первый вариант
Перед командой ставим символ «\»:
# \cat /tmp/test.txtИ всё! Теперь в моем случае alias с batcat проигнорирован и сработала нативная утилита cat. Красота!
Второй вариант
Помещаем команду в кавычки, хоть в двойные хоть в одинарные:
# 'cat' /tmp/test.txtРезультат будет таким же, как и в первом варианте. Алиас заигнорится, запустится коробочный cat.
# "cat" /tmp/test.txt
Третий вариант
Капитанский вариант с указанием полного пути к команде:
# /usr/bin/cat /tmp/test.txtНу тут всё логично, я четко указал что и откуда запускать. Алиасы в пролете. Нативочка в профите.
Чтобы узнать полный путь к команде, воспользуйся одним из этих способов, они очень часто встречаются в bash скриптах, я приводил пример в этом посте.
whereis catЧетвертый вариант
which cat
type -a cat
С помощью команды command
# command cat /tmp/test.txtКоманда command заставляет оболочку рассматривать указанную команду и аргументы как простую команду, подавляя поиск функций оболочки, или отображает информацию о заданных командах.
Пятый вариант
Этот вариант пожалуй более глобальный, который отключает алиасы в текущем сеансе. Не удаляет, а именно «анлиасит» в текущей сессии.
# unalias catХаба-хаба и всё! Теперь у нас в текущей сессии чистый cat, без хвостатых мышек сюси.
А чтобы вообще дропнуть все алиасы в текущей сессии, запускай такое:
# unalias -aНу вот и все, теперь вообще никаких alias’ов нет, голый король. Ну а чтобы не перезапускать сессию и восстановить как было, делаем так:
source ~/.bashrcВозможно в природе есть еще какие-то варианты, но тебе и этих пяти штук будет за глаза.
source ~/.zshrc
Я использую первый вариант, он достаточно быстрый и менее трудозатратный. Ну а если что-то дебажу, то применяют пятый вариант. Для чистоты экспериментов, чтобы на грабли не наступить там где не нужно.
С пятницей коллеги! Хороших тебе предстоящих выходных и береги себя! Пойду дальше мемы для Псины рисовать, забегай если скучно.
Спасибо всем проголосовавшим в этом посте, большинство ЗА, так что в ближайшее время прикручу комменты. Но терзают меня пока сомнения, в общем решим этот вопрос. Увидимся!
tags: #bash #linux
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍161
Привет коллега! Надеюсь ты выжил после выходных и не сорвал спину на мероприятии по копке картофеля. Сегодня у нас с тобой bash.
Мы прекрасно знаем, что bash скрипты выполняются последовательно. Но есть ли способы запускать команды параллельно?
Конечно есть, сейчас про это и поговорим. Покажу два способа как это можно легко осуществить. Первый способ основан на символе &.
Пишем подопытный скрипт:
Wait – команда, которая ожидает завершения определенного процесса, а затем возвращает его состояние завершения.
Оболочка ждет (wait) пока завершатся два предыдущих процесса, прежде чем запустить следующую команду. Получается, все то, что в скрипте идет после wait, будет в режиме ожидания, пока не завершится первый sleep и второй.
Прикольно да? Открываются новые возможности для совершенствования своих костылей. Прям терпко попахивает асинхронностью, в хорошем смысле. Про wait поговорим в отдельном посте, есть там свои клевые фичи.
Теперь давай запустим в терминале последовательно такие команды:
Команда jobs в Linux позволяет пользователю напрямую взаимодействовать с процессами в текущей оболочке. Команда отображает состояние заданий в текущем сеансе.
Запускаем jobs и смотрим:
Давай теперь напишем более наглядный пример, где всё это можно применить.
2. Передает каждую строчку в функцию downloader
3. Функция downloader каждый раз запускается в фоне
4. Происходит скачивание файла по ссылке
5. По завершению (wait) получаемкомпливит complete
Файл url.txt представляет собой список прямых урлов на файлы, которые нужно скачать.
Получается мы не дожидаемся пока скачается первый файл, а сразу скачиваем все пачкой. Мультизагрузка.
Если совсем уж по-простому, то символ & говорит — запусти всё одновременно и параллельно. Типа такого, с таким ты уже всяко встречался:
Это основной вариант, советую его и использовать, теперь давай рассмотрим альтернативные.
Есть еще такая утилита parallel, устанавливается как и все остальное
Углубляться сейчас в parallel особого смысла не вижу, но для общего кругозора ты про нее должен знать. Иногда бывает что для решения задачи подойдет именно parallel, а не нативка с &.
Ну и на закуску, есть такая штука «$!», она позволяет узнать PID последнего запущенного процесса. Давай на примере, запускай:
Вот так это и работает. Ничего сложного. Надеюсь было интересно. Хорошего тебе понедельника, увидимся!
tags: #bash #linux #utils
—
💩 @bashdays
Мы прекрасно знаем, что bash скрипты выполняются последовательно. Но есть ли способы запускать команды параллельно?
Конечно есть, сейчас про это и поговорим. Покажу два способа как это можно легко осуществить. Первый способ основан на символе &.
Пишем подопытный скрипт:
#!/bin/bashЗдесь первая и вторая команда запустятся параллельно. Через 5 секунд на экран выведутся 3 строчки sleep 5_1, sleep 5_2 и sleep 0.
sleep 5 && echo "sleep 5_1" &
sleep 5 && echo "sleep 5_2" &
wait
echo "sleep 0"
Wait – команда, которая ожидает завершения определенного процесса, а затем возвращает его состояние завершения.
Оболочка ждет (wait) пока завершатся два предыдущих процесса, прежде чем запустить следующую команду. Получается, все то, что в скрипте идет после wait, будет в режиме ожидания, пока не завершится первый sleep и второй.
Прикольно да? Открываются новые возможности для совершенствования своих костылей. Прям терпко попахивает асинхронностью, в хорошем смысле. Про wait поговорим в отдельном посте, есть там свои клевые фичи.
Теперь давай запустим в терминале последовательно такие команды:
sleep 60 &На экран выведутся записи вроде таких:
sleep 90 &
sleep 120 &
[1] 38161Это PID процессов которые ты запустил в фоновом режиме. Но интересует нас тут другое. А именно команда jobs.
[2] 38166
[3] 38167
Команда jobs в Linux позволяет пользователю напрямую взаимодействовать с процессами в текущей оболочке. Команда отображает состояние заданий в текущем сеансе.
Запускаем jobs и смотрим:
[1] Done sleep 60Опа! А это список команд, которые мы запустили в фоне. Первое задание завершилось, остальное еще шуршит. Некий мониторинг из коробки.
[2]- Running sleep 90 &
[3]+ Running sleep 120 &
Давай теперь напишем более наглядный пример, где всё это можно применить.
downloader(){
wget -q "$1"
}
while IFS= read -r url
do
downloader "$url" &
done < urls.txt
wait
echo "Downloaded complete"
1. Скрипт читает построчно файл url.txt2. Передает каждую строчку в функцию downloader
3. Функция downloader каждый раз запускается в фоне
4. Происходит скачивание файла по ссылке
5. По завершению (wait) получаем
Файл url.txt представляет собой список прямых урлов на файлы, которые нужно скачать.
Получается мы не дожидаемся пока скачается первый файл, а сразу скачиваем все пачкой. Мультизагрузка.
Если совсем уж по-простому, то символ & говорит — запусти всё одновременно и параллельно. Типа такого, с таким ты уже всяко встречался:
hostname & date & uname &Тут все запустится одновременно и порядок вывода на экран будет каждый раз в своем порядке. Все зависит с какой скоростью отработает команда.
Это основной вариант, советую его и использовать, теперь давай рассмотрим альтернативные.
Есть еще такая утилита parallel, устанавливается как и все остальное
apt/yum/brew install parallel
Делает она то же самое, но имеет более гибкие настройки через параметры. Например, предыдущий пример со скачиванием файлов мог бы выглядеть таким образом:parallel -j 4 wget -q {} < urls.txt
Ключ -j означает сколько джобов будет запараллелено, что-то типа потоков/threads.Углубляться сейчас в parallel особого смысла не вижу, но для общего кругозора ты про нее должен знать. Иногда бывает что для решения задачи подойдет именно parallel, а не нативка с &.
Ну и на закуску, есть такая штука «$!», она позволяет узнать PID последнего запущенного процесса. Давай на примере, запускай:
sleep 60 &В первой команде запустили фоном ожидание 60 секунд, вывелся порядковый номер джобы и PID. Ну а чтобы получить последний PID, выполняем третью команду с «$!». На экран вывелся PID в чистом виде, а дальше можешь его сохранить в переменную и уже проверять в скрипте, завершился он или нет.
[1] 39032
echo $!
39032
Вот так это и работает. Ничего сложного. Надеюсь было интересно. Хорошего тебе понедельника, увидимся!
tags: #bash #linux #utils
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍112 1
Привет еще раз кого не видел. По результатам голосования в тестовом режиме включаю комментарии к постам, для этого я сделал отдельную группу. Группа закрытая, по заявкам. Всех заапрувлю руками, чтобы gpt/шл%ха ботов на корню отсечь.
Кому интересно, оставляйте заявку. Комменты появятся только к новым постам, такая уж особенность в телеграм.
Потестим до конца сентября. Если будет толк, то оставим. Ну а если нет, то тоже оставим, но забаним душнил и провокаторов. Я надеюсь будет всем интересно пересечься с единомышленниками и затереть за прекрасное.
Каждый из вас обладает эксклюзивными знаниями и иногда так и хочется сказать — даблять блин! Это делается вот так! Есть такая утилита, не знал что ли? У тебя тут ошибка, я бы сделал так! Короче Велком to BASH DAYS|CHAT.
Ну а кто проголосовал против, просто не обращайте внимания на дополнительную кнопку с комментариями, включайте зрительный adblock и наслаждайтесь контентом как и раньше.
Жму руку! Ну и котики:😎 😊 👍
Кому интересно, оставляйте заявку. Комменты появятся только к новым постам, такая уж особенность в телеграм.
Потестим до конца сентября. Если будет толк, то оставим. Ну а если нет, то тоже оставим, но забаним душнил и провокаторов. Я надеюсь будет всем интересно пересечься с единомышленниками и затереть за прекрасное.
Каждый из вас обладает эксклюзивными знаниями и иногда так и хочется сказать — да
Ну а кто проголосовал против, просто не обращайте внимания на дополнительную кнопку с комментариями, включайте зрительный adblock и наслаждайтесь контентом как и раньше.
Жму руку! Ну и котики:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍98
This media is not supported in your browser
VIEW IN TELEGRAM
Йо! Мини пост. Хочешь погонять змея и ничего при этом не устанавливать? Запускай в консольке:
Отлично отключает голову, после восьми часового дебагинга. Денёк сегодня, конечно вообще атас.
А кто еще какие игрули консольные знает без геморной установки? Кидай в комменты, заценим!
tags: #bash #games
—
💩 @bashdays
bash <(curl -s https://raw.githubusercontent.com/wick3dr0se/snake/main/snake)Игруха создана на чистом bash v5.1+. Плюсом можно потренить навигацию в VIM используя hjkl, ну и стрелочки никто не отменял.
Отлично отключает голову, после восьми часового дебагинга. Денёк сегодня, конечно вообще атас.
А кто еще какие игрули консольные знает без геморной установки? Кидай в комменты, заценим!
tags: #bash #games
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍93
Вчера оказывается столько праздников было, уууу. И день журавля, и день парикмахера, и день пирога и день программиста. Но вместо того чтобы весело пить пиво и есть шарлотку, я как обычно занимался какой-то «очень полезной» шляпой.
Когда тебе навязывают зеленых стажеров, так или иначе сталкиваешься с шарингом своего экрана. Чтобы наглядно показывать будущему поколению крючочки и закорючки. Визуально информация усваивается гораздо лучше.
Раньше я просто шарил экран в гугол мите, но всё это дело было очень прожорливым для моего ноута. Расшариваю я в основном консольку, показываю ребятам какие команды ввожу, что и как запускаю.
И пришел я однажды к прозрению — из лука весом в тысячу кан не стреляют по мышам. Зачем мне какой-то всратый гугол мит? Есть же прекрасная утилита, которая называется tty-share.
Кан - японская единица измерения массы, равная 10 хиакумэ. Не знаю зачем тебе эта информация, просто живи теперь с ней.
tty-share - простейший инструмент, который используется для предоставления общего доступа к терминалу Linux/OSX через интернет. Написан на GO и само собой кроссплатформенный без зависимостей. Можно даже на малине (Raspberry Pi) эту чертяку запускать.
Как это работает. Идем в терминал и устанавливаем
После установки вбиваем и запускаем:
Все что я ввожу и запускаю в своей консоли, отображается у стажеров в браузере.
Ключ
По моему это офигительно! Работает за любым NAT. Так же есть и локальная сессия (local session), если вы находитесь в одной подсети, можно не указывать ключ
У tty-share есть масса других возможностей, можно менять порты, пускать через проксю, указывать оболочку (bash/zsh/etc), писать логи и многое другое. Загляни в хелп (
Мне достаточно двух public и readonly, остальное нафиг, работает и хорошо. По безопасности там TLS и https, но разработчик обещает добавить сквозное шифрование, пароли и ключи. Подробнее можешь почитать в разделе docs на странице проекта.
А как завершать сессию?А хуй его знает. В доке есть упоминание про ключ
Залил гифки работы tty-share в телеграф, глянуть можешь тут.
🔵 сайт проекта
🐱 репозиторий на github
альтернативы:
- Instant terminal sharing
- VSCode Live Share
Пользуйся на здоровье. Хорошего тебе дня, увидимся!
UPD: Наш коллега Egor нашел способ завершить сессию, просто вводишь exit и вуаля! Спасибо Egor!
tags: #linux #utils
—
💩 @bashdays
Когда тебе навязывают зеленых стажеров, так или иначе сталкиваешься с шарингом своего экрана. Чтобы наглядно показывать будущему поколению крючочки и закорючки. Визуально информация усваивается гораздо лучше.
Раньше я просто шарил экран в гугол мите, но всё это дело было очень прожорливым для моего ноута. Расшариваю я в основном консольку, показываю ребятам какие команды ввожу, что и как запускаю.
И пришел я однажды к прозрению — из лука весом в тысячу кан не стреляют по мышам. Зачем мне какой-то всратый гугол мит? Есть же прекрасная утилита, которая называется tty-share.
Кан - японская единица измерения массы, равная 10 хиакумэ. Не знаю зачем тебе эта информация, просто живи теперь с ней.
tty-share - простейший инструмент, который используется для предоставления общего доступа к терминалу Linux/OSX через интернет. Написан на GO и само собой кроссплатформенный без зависимостей. Можно даже на малине (Raspberry Pi) эту чертяку запускать.
Как это работает. Идем в терминал и устанавливаем
apt/brew install tty-share либо затаскиваем бинарник с гитхаба.После установки вбиваем и запускаем:
tty-share --public --readonlyполучаем такое:
public session: https://on.tty-share.com/mbeD30O8tEoWr4_4/Жмем Enter и погнали! Первая строчка public session, она мне и нужна. Копирую URL и отдаю стажерам, они вбивают этот URL в браузер и видят мою расшаренную консоль.
local session: http://localhost:8000/s/local/
Press Enter to continue!
Все что я ввожу и запускаю в своей консоли, отображается у стажеров в браузере.
Ключ
--readonly делает так, чтобы «прямые руки» моих подопечных не могли вмешиваться в процесс просвещения. Да, если этот ключ не указать, то стажеры смогут через свой браузер вбивать команды в мою консоль.По моему это офигительно! Работает за любым NAT. Так же есть и локальная сессия (local session), если вы находитесь в одной подсети, можно не указывать ключ
--public и довольствоваться локалкой.У tty-share есть масса других возможностей, можно менять порты, пускать через проксю, указывать оболочку (bash/zsh/etc), писать логи и многое другое. Загляни в хелп (
--help) если интересно. Мне достаточно двух public и readonly, остальное нафиг, работает и хорошо. По безопасности там TLS и https, но разработчик обещает добавить сквозное шифрование, пароли и ключи. Подробнее можешь почитать в разделе docs на странице проекта.
А как завершать сессию?
-detach-keys, но из коробки ctrl-o, ctrl-c не работает, либо я совсем буратино. Поэтому когда мне нужно убить public session, я просто сделал себе alias на такую команду:kill $(ps aux | grep 'tty-share' | awk '{print $2}')
Если разберешься как нативно прикончить сессию, пиши в комменты, скину тебе картинку с котиком.Залил гифки работы tty-share в телеграф, глянуть можешь тут.
альтернативы:
- Instant terminal sharing
- VSCode Live Share
Пользуйся на здоровье. Хорошего тебе дня, увидимся!
UPD: Наш коллега Egor нашел способ завершить сессию, просто вводишь exit и вуаля! Спасибо Egor!
tags: #linux #utils
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍149
Задался вопросом какая же все-таки оболочка быстрее? У меня на серверах можно встретить такой зоопарк: sh, bash, ksh, mksh, posh, zsh. Почему так много? Не знаю, сервера достались по наследству, видимо остатки от давно сгинувших девопсов по реке Стикс.
На своей локальной машине использую исключительно zsh со всякими наворотами:
🐱 Oh My Zsh - прибомбасина для zsh
🐱 autosuggestions - автокомплит
На серверах алогично Oh My Zsh + autosuggestions ну и нативный bash для скриптов, все остальное — неведомая хрень.
Автокомплит мастхев, экономит кучу времени, чтобы не тыкать стрелочку вниз вверх. Вводишь начало команды и оно тебе с хистори автоматом уже подгоняет варианты. Не надо каждый раз упарываться и писать всю команду целиком. Удобно!
Дополнительно из плагинов включаю🐱 zsh-syntax-highlighting чтобы красивенько было. Ну а чтобы каждый раз не указывать ssh ключи при подключении к серверам, использую встроенный плагин ssh-agent.
Запустим этот скрипт в bash:
После запуска получаю: 0m1.242s
Скрипт отслеживает точное время открытия шелла 1000 раз без выполнения каких-либо операций.
Ок, теперь давай запустим этот скрипт в zsh:
Не такие и большие различия. Даже можно сказать ничтожные. Но это всего лишь один тест. Чтобы получить какие-то средние значения воспользуемся утилитой:
🐱 shellbench
Устанавливаем и запускаем:
Хм, в совокупности тестов получается что zsh где-то прям намного шустрее, да даже ни где-то, а прям почти лидирует в производительности.
По большей части это писькомерство, ну работает оно и работает, какая разница насколько быстрее. Да, соглашусь, но пару раз встречал ребят которым ставили задачу на оптимизацию выполнения скриптов, где важна каждая секунда. Это как у оверклокеров, где каждый герц и фпс это уже победа.
Вывод: По результатам тестов, zsh оказался быстрее чем bash, но не везде. Опять-же тут все индивидуально.
Кстати когда запускаешь на macos midnight commander + zsh в роле оболочки, то mc запускается прям кое как, секунды три наверное. Поэтому с mc я использую bash, можно конечно этот момент отдебажить, но мне лень. Если когда-нибудь руки дойдут, напишу как пофиксил.
А вообще самая быстрая оболочка это Dash (Debian Almquist Shell). Это POSIX-совместимая реализация Bourne Shell. Она заменяет /bin/sh в скриптах по умолчанию и обеспечивает улучшенную скорость, потребляя при этом меньше ресурсов. Dash превосходит bash/zsh по производительности, но его нельзя использовать, так как он не предназначен для взаимодействия.
❓ А какую оболочку используешь ты и почему?
Кстати всем привет! Надеюсь твои выходные прошли без проишествий. Увидимся!
tags: #linux #utils
—
💩 @bashdays
На своей локальной машине использую исключительно zsh со всякими наворотами:
На серверах алогично Oh My Zsh + autosuggestions ну и нативный bash для скриптов, все остальное — неведомая хрень.
Автокомплит мастхев, экономит кучу времени, чтобы не тыкать стрелочку вниз вверх. Вводишь начало команды и оно тебе с хистори автоматом уже подгоняет варианты. Не надо каждый раз упарываться и писать всю команду целиком. Удобно!
Дополнительно из плагинов включаю
plugins=(git zsh-syntax-highlighting zsh-autosuggestions ssh-agent)
zstyle :omz:plugins:ssh-agent agent-forwarding on
zstyle :omz:plugins:ssh-agent identities home_rsa work_rsa2 her_rsa3
zstyle :omz:plugins:ssh-agent lifetime
Вернемся в теме - кто быстрее. Очевидно же что bash! Давай убедимся.Запустим этот скрипт в bash:
for i in $(seq 1 1000);
do bash -c ":" ;
done
Запускаем через time: time bash speed.sh
time - оценивает по времени производительность любой задачи, выводя после её завершения затраченное время: реальное, пользователя и системы. Через time можешь оценивать производительность по времени любых своих скриптов.После запуска получаю: 0m1.242s
Скрипт отслеживает точное время открытия шелла 1000 раз без выполнения каких-либо операций.
Ок, теперь давай запустим этот скрипт в zsh:
time zsh speed.sh
Результат: 0m1.344sНе такие и большие различия. Даже можно сказать ничтожные. Но это всего лишь один тест. Чтобы получить какие-то средние значения воспользуемся утилитой:
Устанавливаем и запускаем:
git clone https://github.com/shellspec/shellbench.git .
shellbench -s bash,zsh sample/*
По итогу получаем около 28ми тестов. На картинке можешь глянуть мои результаты. Числа в таблице это - количество выполнений в секунду.Хм, в совокупности тестов получается что zsh где-то прям намного шустрее, да даже ни где-то, а прям почти лидирует в производительности.
По большей части это писькомерство, ну работает оно и работает, какая разница насколько быстрее. Да, соглашусь, но пару раз встречал ребят которым ставили задачу на оптимизацию выполнения скриптов, где важна каждая секунда. Это как у оверклокеров, где каждый герц и фпс это уже победа.
Вывод: По результатам тестов, zsh оказался быстрее чем bash, но не везде. Опять-же тут все индивидуально.
Кстати когда запускаешь на macos midnight commander + zsh в роле оболочки, то mc запускается прям кое как, секунды три наверное. Поэтому с mc я использую bash, можно конечно этот момент отдебажить, но мне лень. Если когда-нибудь руки дойдут, напишу как пофиксил.
А вообще самая быстрая оболочка это Dash (Debian Almquist Shell). Это POSIX-совместимая реализация Bourne Shell. Она заменяет /bin/sh в скриптах по умолчанию и обеспечивает улучшенную скорость, потребляя при этом меньше ресурсов. Dash превосходит bash/zsh по производительности, но его нельзя использовать, так как он не предназначен для взаимодействия.
Кстати всем привет! Надеюсь твои выходные прошли без проишествий. Увидимся!
tags: #linux #utils
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81
Возможно ли на bash отрендерить какой-нибудь шаблон? Например, как в ansible? Конечно возможно! Сейчас покажу.
Давай возьмем огрызок конфига nginx и сделаем из него шаблон под разное окружение. У меня будет 2 сервера, естественно production и до кучи возьмем stage.
Создаем шаблон: nginx.tpl
Еще есть фича с созданием файла через
Так, поехали рендерить:
Далее вызываем функцию render и передаем в нее nginx_user и pid_path. Функция render всё это дело экспортирует в переменные окружения, а затем с помощью envsubst заменяет их в шаблоне. Готовый конфиг сразу попадает в папку с nginx.Охуенно! Кайф!
envsubst - заменяет переменную окружения новым значением в формате строки оболочки командной строки. Переменные могут быть заменены в формате ${var} или $var
Если у тебя много переменных, то можешь их разом экспортировать через цикл. В предыдущих постах у меня где-то есть примеры таких циклов.
Собственно на этом можно и заканчивать. В 99% случаев все используют какой-то вонючий perl, sed, eval и т.п. Но решение с envsubst намного гибче и элегантнее.
Есть еще вариант с Heredoc. Heredoc-синтаксис — способ определения строковых переменных в исходном коде программ.
Пример скрипта, делает то же самое. Логику добавлять не стал:
tags: #linux #bash
—
💩 @bashdays
Давай возьмем огрызок конфига nginx и сделаем из него шаблон под разное окружение. У меня будет 2 сервера, естественно production и до кучи возьмем stage.
Создаем шаблон: nginx.tpl
user ${nginx_user};
worker_processes auto;
pid ${pid_path};
include /etc/nginx/modules/*.conf
Всё то, что нужно отрендерить, располагаем в ${параметр}.
Создаем скрипт с логикой:>> nginx_gen.sh && chmod +x nginx_gen.shСимволы «>>» означают - создать новый файл. А чмодиком делаем файл покорным и исполняемым.
Еще есть фича с созданием файла через
touch nginx_gen.sh. Если запустить команду с touch повторно, то файл не перетрется, НО у него обновится дата и время создания. Иногда бывает полезно обновлять дату и время каким-нибудь файлам, которые выполняют роль флагов.Так, поехали рендерить:
#!/bin/bashРазбираем портянку. Логика простая, если hostname равен production, то присваиваем одни переменные. Во всех других случаях присваиваем другие переменные.
function render {
export nginx_user=$1 pid_path=$2
cat nginx.tpl | envsubst > /etc/nginx/nginx.conf
}
if [[ $(hostname) == "production" ]]; then
nginx_user="www-data"
pid_path="/run/nginx.pid"
render $nginx_user $pid_path
else
nginx_user="nginx"
pid_path="/var/run/nginx.pid"
render $nginx_user $pid_path
fi
Далее вызываем функцию render и передаем в нее nginx_user и pid_path. Функция render всё это дело экспортирует в переменные окружения, а затем с помощью envsubst заменяет их в шаблоне. Готовый конфиг сразу попадает в папку с nginx.
envsubst - заменяет переменную окружения новым значением в формате строки оболочки командной строки. Переменные могут быть заменены в формате ${var} или $var
Если у тебя много переменных, то можешь их разом экспортировать через цикл. В предыдущих постах у меня где-то есть примеры таких циклов.
Собственно на этом можно и заканчивать. В 99% случаев все используют какой-то вонючий perl, sed, eval и т.п. Но решение с envsubst намного гибче и элегантнее.
Есть еще вариант с Heredoc. Heredoc-синтаксис — способ определения строковых переменных в исходном коде программ.
Пример скрипта, делает то же самое. Логику добавлять не стал:
#!/bin/bashОтрендерится как нужно, но мне все же ближе вариант с envsubst. Нагляднее чтоли. Выбор лишь за тобой, на каком велосипеде кататься. Вот такие пироги. Ладно, побежал я дальше работу работать. Будьте здоровы! Увидимся!
nginx_user="www-data"
pid_path="/var/run/nginx.pid"
cat > /etc/nginx/nginx.conf << EOF
user ${nginx_user};
worker_processes auto;
pid ${pid_path};
include /etc/nginx/modules-enabled/*.conf;
EOF
tags: #linux #bash
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍88
Приходила идея спарсить весь github?
Мне нет! А вот некому чуваку такая идея пришла и он замутил интерактивную карту по открытым git репозиториям. По итогу коллекция составила более чем 400к репозиториев. Масштабно, ничего не скажешь. Ну собрал и собрал, нам то какое дело? Читай дальше!
А самое главное тут, что под все эти данные, он сделал интерактивную онлайн карту. Каждая «страна» на карте это репозитории, написанные на одном языке или фреймворке. Например, Pythonia = Python, а Swiftoria - на Swift.
Имена стран генерились с помощью chatgpt таким запросом:
И даже поиск работает, чудо🍴 Можно натолкнуться на достаточно интересные штуки, которые известны лишь узкому числу лиц и особо нигде не пиарятся.
Потыкать карту можешь:🐱 тут.
Страница проекта с подробностями:🐱 тут.
ps: Идея для стартапа: Сделать интерактивную карту с данными pornhub. Чтобы тыкнул и видосики-видосики.
tags: #services #git
—
💩 @bashdays
Мне нет! А вот некому чуваку такая идея пришла и он замутил интерактивную карту по открытым git репозиториям. По итогу коллекция составила более чем 400к репозиториев. Масштабно, ничего не скажешь. Ну собрал и собрал, нам то какое дело? Читай дальше!
А самое главное тут, что под все эти данные, он сделал интерактивную онлайн карту. Каждая «страна» на карте это репозитории, написанные на одном языке или фреймворке. Например, Pythonia = Python, а Swiftoria - на Swift.
Имена стран генерились с помощью chatgpt таким запросом:
Please analyze these repository and detect a common theme (e.g. programming language, technology, domain). Pay attention to language too (english, chinese, korean, etc.). If there is no common theme found, please say so. Otherwise, If you can find a strong signal for a common theme please come up with a specific name for imaginary country that contains all these repositories. Give a few options. When you give an option prefer more specific over generic option (for example if repositories are about recommender systems, use that, instead of generic DeepLearning)Хм, буду теперь названия переменных придумывать таким способом, пусть проклятые роботы за меня пашут.
И даже поиск работает, чудо
Потыкать карту можешь:
Страница проекта с подробностями:
ps: Идея для стартапа: Сделать интерактивную карту с данными pornhub. Чтобы тыкнул и видосики-видосики.
tags: #services #git
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍112
Всем доброе утро, день, вечер, ночь. Наконец-то выходные и слак с моттермостом немного подзаткнулись. Сегодня рассмотрим ситуацию, когда ты случайно/специально удалил исполняющийся bash скрипт.
Ситуация: У меня в фоне на сервере крутится bash скрипт, который отслеживает какие-то процессы. Работает годами, но приходит коллега и случайно/специально зачищает папку /usr/local/sbin. Опа и скрипта моего больше нет. Мне чо его заново что ли писать?Блять! Жопа!
Чтобы не попадать в такие ситуации, всегда храни исходники в git. Соглашусь, что это избыточно, но подложить соломку никогда не будет лишним.
Ладно. Скрипт мой сгинул, в git я его не положил. Чо делать? Так. Скрипт удалён с диска, но продолжает крутиться в фоне, это уже хорошо. Значит его можно как-нибудь восстановить. Сейчас покажу как.
Давай создадим подопытный скрипт:
Так, скрипт запустили, он крутится у нас фоне, давай теперь удалим сам файл:
Окей. Файл удалили. Как восстановить? Выполняем:
Почему это возможно? А почему бы и нет! В следующих постах расскажу про общую концепцию удаления файлов в Linux и все станет прозрачным.
Про восстановление файлов на диске, я как-то ранее уже писал тут, но там была немного другая история (когда мы знаем physical_offset).
☑️ читать:
tags: #linux #bash
—
💩 @bashdays
Ситуация: У меня в фоне на сервере крутится bash скрипт, который отслеживает какие-то процессы. Работает годами, но приходит коллега и случайно/специально зачищает папку /usr/local/sbin. Опа и скрипта моего больше нет. Мне чо его заново что ли писать?
Чтобы не попадать в такие ситуации, всегда храни исходники в git. Соглашусь, что это избыточно, но подложить соломку никогда не будет лишним.
Ладно. Скрипт мой сгинул, в git я его не положил. Чо делать? Так. Скрипт удалён с диска, но продолжает крутиться в фоне, это уже хорошо. Значит его можно как-нибудь восстановить. Сейчас покажу как.
Давай создадим подопытный скрипт:
touch /tmp/script.sh и закинем в него такое:#!/bin/bashДелаем исполняемым
sleep 1000
exit
chmod +x /tmp/script.sh и запускаем в фоне /tmp/script.sh &
Символ & может служить разделителем между командами command & command, две команды выполнятся параллельно.Так, скрипт запустили, он крутится у нас фоне, давай теперь удалим сам файл:
rm -f /tmp/script.sh ключ -f = force, удалит без лишних вопросов.Окей. Файл удалили. Как восстановить? Выполняем:
lsof -c 'script.sh'На экран выкатится портянка, нам нужна строка где в конце указан путь до скрипта, который был удален:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEБерем PID = 261899, берем FD = 255 и делаем сальто-мортале:
script.sh 261899 root 255r REG 8,1 51 130773 /tmp/script.sh
cat /proc/261899/fd/255Опачки, что мы видим? Исходник скрипта, который мы удалили:
File: /proc/261899/fd/255Копипастим, вставляем, сохраняем и гордимся своими охренительными скиллами.
#!/bin/bash
sleep 1000
exit
Почему это возможно? А почему бы и нет! В следующих постах расскажу про общую концепцию удаления файлов в Linux и все станет прозрачным.
Про восстановление файлов на диске, я как-то ранее уже писал тут, но там была немного другая история (когда мы знаем physical_offset).
man 5 proc # /proc/[pid]/fd/Всем хороших выходных и берегите себя!
man lsof
tags: #linux #bash
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍211
Не всегда есть возможность писать bash скрипты у себя на локальной машине. К примеру у меня есть ноут где торчит винда чисто под бухгалтерские штуки и мне лень туда запихивать какой-то wsl и т.п.
Но порой нужно как-то быстренько накидать скрипт и отдать его заказчику, ждать он не будет. Да и бывает в дороге с телефона можно нормально так покодить.
Для этого я пользуюсь онлайн редакторами-компиляторами, которые отлично интегрированы с bash.
1. Rextester - bash version: 4.4.20
2. Mycompiler - bash version: 5.1.16
3. Leetcode - bash version: 5.0.17
Я пользуюсь Mycompiler, по большей части из-за свежей версии. Все написанные скрипты, можно сохранить в самом сервисе, а также легко поделиться с кем-то по расшаренной ссылке. Ну и есть некое подобие GIT, где можно форкнуться от какого-то своего проекта.
Помимо bash, присутствует еще куча других языков и компиляторов, этакий швейцарский ножик на все случаи жизни.
Что прикольно, через скрипт можно создать какой-нибудь подопытный файл например
В общем тыкайте кому интересно. Конечно использование локального bash будет более правильным решением, но в каких-то случаях выручают именно онлайн сервисы, тем более они бесплатные.
После интеграции от партнера будет еще один пост на техническую тему, так что далеко не отключайтесь. Да, всем привет! Спасибо ребят, кто подбустил и дал возможность выкладывать сторисы.
tags: #services #bash
—
💩 @bashdays
Но порой нужно как-то быстренько накидать скрипт и отдать его заказчику, ждать он не будет. Да и бывает в дороге с телефона можно нормально так покодить.
Для этого я пользуюсь онлайн редакторами-компиляторами, которые отлично интегрированы с bash.
1. Rextester - bash version: 4.4.20
2. Mycompiler - bash version: 5.1.16
3. Leetcode - bash version: 5.0.17
Я пользуюсь Mycompiler, по большей части из-за свежей версии. Все написанные скрипты, можно сохранить в самом сервисе, а также легко поделиться с кем-то по расшаренной ссылке. Ну и есть некое подобие GIT, где можно форкнуться от какого-то своего проекта.
Помимо bash, присутствует еще куча других языков и компиляторов, этакий швейцарский ножик на все случаи жизни.
Что прикольно, через скрипт можно создать какой-нибудь подопытный файл например
echo "test" >> /tmp/test.txt и потом с ним продолжить работу прям из скрипта cat /tmp/test.txt. То есть редакторы позволяют работать с файловой системой и не ограничены лишь компиляцией.В общем тыкайте кому интересно. Конечно использование локального bash будет более правильным решением, но в каких-то случаях выручают именно онлайн сервисы, тем более они бесплатные.
После интеграции от партнера будет еще один пост на техническую тему, так что далеко не отключайтесь. Да, всем привет! Спасибо ребят, кто подбустил и дал возможность выкладывать сторисы.
tags: #services #bash
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍75
И снова привет. Есть такие утилиты base64/base32/basenc которые кодируют/декодируют информацию, наверняка ты про них знаешь. Так вот, если утилита встречает во входных данных некорректный символ, она прекращает свою работу. Например:
Алфавит кодирования содержит латинские символы A-Z, a-z, цифры 0-9 (всего 62 знака) и 2 дополнительных символа.
В приведенном выше примере, символ «!» не входит в этот алфавит. Чтобы декодировать данные, можно удалить символ восклицательного знака. Но мы с вами калачи тертые и любим всё необычное. Поэтому просто указываем ключ -i и все символы, которые не входят в алфавит кодирования, просто-напросто будет проигнорирован.Заебись! Хорошо!
Вставляя «плохие» символы в закодированную строку, мы можем как бы запретить декодирование. Этакий анти скрипт-кидди получается. Наивный замочек.
Вставлять «плохие» символы можно в любую часть строки. При раскодировании с ключом -i все эти «плохие» символы будут проигнорированы, где бы они ни были и замочек откроется.
Типа того (вставил ! в середину строки):
Таким образом можно защищать передаваемые данные между фронтом и бэкендом по API. Отловил кто-то POST запрос, выудил из него закодированную строку base64, а расшифровать не получается.
Если тонкостей не знать, на этом все и закончится. Никто особо не будет ковыряться в огромном закодированном тексте и искать, что не так.
100 лет назад были малвари которые управлялись из твиттера. Малваря заражала машину, потом лезла в твиттер, искала по-индивидуальному хэштегу сообщение, находило его и выполняла инструкции на зараженной машине.
Сообщение выглядело безобидно, но в конце содержались закодированные команды, с помощью которых и управлялась малваря. Такой способ избавлял злоумышленников от необходимости завязываться на контрольный центр, который в любой момент могли заблокировать по домену или айпишке. Эхх… были времена.
Ладно, надеюсь было познавательно, всем добра!
tags: #linux #utilites
—
💩 @bashdays
echo '!0LPQsNCy0L3Qvg==' | base64 -dА как она понимает какой корректный символ, а какой нет? А тот который входит в алфавит кодирования. Символ новой строки, также входит в этот алфавит и просто игнорируется утилитой, где бы этот символ не находился.
base64: invalid input
Алфавит кодирования содержит латинские символы A-Z, a-z, цифры 0-9 (всего 62 знака) и 2 дополнительных символа.
В приведенном выше примере, символ «!» не входит в этот алфавит. Чтобы декодировать данные, можно удалить символ восклицательного знака. Но мы с вами калачи тертые и любим всё необычное. Поэтому просто указываем ключ -i и все символы, которые не входят в алфавит кодирования, просто-напросто будет проигнорирован.
echo '!0LPQsNCy0L3Qvg==' | base64 -diОпа! И нам тут даже восклицательный знак не помеха, закодированный текст успешно вывелся.
Вставляя «плохие» символы в закодированную строку, мы можем как бы запретить декодирование. Этакий анти скрипт-кидди получается. Наивный замочек.
Вставлять «плохие» символы можно в любую часть строки. При раскодировании с ключом -i все эти «плохие» символы будут проигнорированы, где бы они ни были и замочек откроется.
Типа того (вставил ! в середину строки):
echo '0LPQsNC!y0L3Qvg==' | base64 -diЗакодированная срока успешно раскодируется. А если пойти дальше, можно в обычном тексте передавать закодированные данные:
echo 'Съешь ещё этих мягких французских булок и разжирей 0YXRg9C5' | base64 -diТекст в игнор, а данные раскодируются.
Таким образом можно защищать передаваемые данные между фронтом и бэкендом по API. Отловил кто-то POST запрос, выудил из него закодированную строку base64, а расшифровать не получается.
Если тонкостей не знать, на этом все и закончится. Никто особо не будет ковыряться в огромном закодированном тексте и искать, что не так.
100 лет назад были малвари которые управлялись из твиттера. Малваря заражала машину, потом лезла в твиттер, искала по-индивидуальному хэштегу сообщение, находило его и выполняла инструкции на зараженной машине.
Сообщение выглядело безобидно, но в конце содержались закодированные команды, с помощью которых и управлялась малваря. Такой способ избавлял злоумышленников от необходимости завязываться на контрольный центр, который в любой момент могли заблокировать по домену или айпишке. Эхх… были времена.
Ладно, надеюсь было познавательно, всем добра!
tags: #linux #utilites
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍148
Пум пурум, сегодня еще один неочевидный способ восстановить удаленные файлы в Linux. Я знаю, ты такое любишь. Первый способ описывал тут, второй тут.
Валяется у меня скриптик ~/fs.sh, приходит жопарукий Петя и удаляет его через rm -rf ~/fs.sh. Козлина! Ни о какой корзине речь и идти не может.
Но я примерно помню, что было внутри. А было там нечто подобное:
Во вторых запускаем команду:
Теперь по ключам:
-a = осуществляем поиск в бинарных файлах.
-C = сколько строк выводить ДО и ПОСЛЕ каждого совпадения строки.
То есть у меня совпала строка Fucking, если я не укажу -С 200, то увижу в выводе только echo "Fucking". А нам то нужно восстановить весь скрипт полностью. Поэтому и нужно сказать грепу, давай еще выведи 200 строк до и 200 после.
Кстати с ключом -C удобно грепать логи какого нибудь php, где нужно посмотреть контекст ошибки, обычно она на несколько строк простилается.
-F = строка, по которой будем искать.
Естественно указываем свой раздел диска, у меня это /dev/sda1, у тебя может быть что-то совсем другое. Учти этот момент.
Почему это работает? Если коротко - мы воспользовались философией Unix, которая гласит — Всё есть файл!
Такие дела. Чётко и полезно, забирай в копилку знаний. Вечерком еще что-нибудь интересное напишу, пока правда не знаю про что. На связи!
tags: #linux #recovery
—
💩 @bashdays
Валяется у меня скриптик ~/fs.sh, приходит жопарукий Петя и удаляет его через rm -rf ~/fs.sh. Козлина! Ни о какой корзине речь и идти не может.
Но я примерно помню, что было внутри. А было там нечто подобное:
#!/bin/bashЧто делать? Ну во первых прописываем прицельную двоечку в безмозглую кабину Пете. Ну а если ты на удаленке, то просто пишем в корпоративную аську — Пётр, вы 3.14дарасина.
echo "Fucking"
exit 1
Во вторых запускаем команду:
grep -a -C 200 -F 'Fucking' /dev/sda1Оно там подумает какое-то время и начнет вываливать на экран всякий мусор. Ну а среди этого мусора будет удалённый исходник скрипта. Копипастим/Вставляем и снова радуемся своим скиллам.
Теперь по ключам:
-a = осуществляем поиск в бинарных файлах.
-C = сколько строк выводить ДО и ПОСЛЕ каждого совпадения строки.
То есть у меня совпала строка Fucking, если я не укажу -С 200, то увижу в выводе только echo "Fucking". А нам то нужно восстановить весь скрипт полностью. Поэтому и нужно сказать грепу, давай еще выведи 200 строк до и 200 после.
Кстати с ключом -C удобно грепать логи какого нибудь php, где нужно посмотреть контекст ошибки, обычно она на несколько строк простилается.
-F = строка, по которой будем искать.
Естественно указываем свой раздел диска, у меня это /dev/sda1, у тебя может быть что-то совсем другое. Учти этот момент.
Почему это работает? Если коротко - мы воспользовались философией Unix, которая гласит — Всё есть файл!
Такие дела. Чётко и полезно, забирай в копилку знаний. Вечерком еще что-нибудь интересное напишу, пока правда не знаю про что. На связи!
tags: #linux #recovery
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍200 4
В прошлом посте я затронул тему с grep, так вот. У grep есть хороший ключик -q. При указании этого ключа, утилита прекращает свою работу, как только нашлась заданная подстрока. Это правильная оптимизация и ей нужно пользоваться если нужно проверить наличие подстроки в файле.
Давай попрактикуемся и с помощью strace посмотрим, как чо там в кишках происходит. Создаем большой файл и забиваем его рандомными данными:
Так, файл размером 1G готов /tmp/large, дальше запускаем:
-P = путь до файла
-y = выводит имя пути до файла
-e = команда которую дебажим
Через секунду, на выходе получаем нечто подобное:
Делаем то же самое без strace и проверяем статус выхода, все ли идентично:
Если коротко, некоторые версии grep с ключом -q могут вернуть статус выхода 2. Так что на разных системах работать может по-разному. Если в своих скриптах проверяешь эти статусы, логика может сломаться, будь аккуратнее с этим.
Еще нюанс, можно добиться такого же поведения grep, но без ключа -q. Это сработает, если вывод перенаправлен в /dev/null. Ну это и логично, нам не нужен никакой вывод на экран и нет никакого смысла продолжать читать огромный файл если подстрока уже найдена.
Вроде не сложно рассказал, по крайней мере попытался. Ладно, рад всех видеть, побежал дальше работу работать, сумасшедший какой-то день. Пока пока!
tags: #linux #bash #debug
—
💩 @bashdays
Давай попрактикуемся и с помощью strace посмотрим, как чо там в кишках происходит. Создаем большой файл и забиваем его рандомными данными:
head -c 1G /dev/urandom > /tmp/largeЕсли head не понимает буковку G в размере, то указываем явный размер файла: -c
1073741824.Так, файл размером 1G готов /tmp/large, дальше запускаем:
strace -P /tmp/large -ye read grep -q 's' /tmp/largeКлючи:
-P = путь до файла
-y = выводит имя пути до файла
-e = команда которую дебажим
Через секунду, на выходе получаем нечто подобное:
read(3</tmp/large>, "v\310*A\307\16\324m&V8H\202\326\177\244\3059\27}00_\274\300<\245.X\27\310`"..., 98304) = 98304То есть с опцией -q, grep не стал читать полностью весь гигабайтный файл, а сделал лишь один системный вызов read(3</tmp/large) и тут же завершил работу. Искомая строка нашлась, вернулся статус 0. Про статусы выхода я писал в этом посте.
+++ exited with 0 +++
Делаем то же самое без strace и проверяем статус выхода, все ли идентично:
grep -q 's' /tmp/largeНа выходе у нас будет 0. Ок, эксперимент завершился успехом. Некоторые версии grep могут возвращать истину если ошибка произошла не связанная с поиском. Этот момент нужно учитывать. Про такие случаи хорошо написано здесь.
echo $?
Если коротко, некоторые версии grep с ключом -q могут вернуть статус выхода 2. Так что на разных системах работать может по-разному. Если в своих скриптах проверяешь эти статусы, логика может сломаться, будь аккуратнее с этим.
Еще нюанс, можно добиться такого же поведения grep, но без ключа -q. Это сработает, если вывод перенаправлен в /dev/null. Ну это и логично, нам не нужен никакой вывод на экран и нет никакого смысла продолжать читать огромный файл если подстрока уже найдена.
strace -P /tmp/large -ye read grep 's' /tmp/large > /dev/nullУтилита grep (без ключа -q) так же сделает один системный вызов read и прекратит свою работу, как только найдет первое совпадение.
Вроде не сложно рассказал, по крайней мере попытался. Ладно, рад всех видеть, побежал дальше работу работать, сумасшедший какой-то день. Пока пока!
tags: #linux #bash #debug
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍94
Привет. Что-то мало мне было двух выходных, надеюсь хоть ты отдохнул от информационного шума. Ладно, к делу. В предыдущем посте мы с тобой рассмотрели линтер для bash. А сегодня познакомимся с утилитой shfmt.
Это не очередной линтер (но то же умеет орать на ошибки), это утилита для форматирования и синтаксического анализа скриптов. Байда написана на golang и поддерживает оболочки POSIX, Bash и mksh. Так что утилита не ограничена одним лишь bash.
Ставится из пакетного менеджера
«наверное» работоспособность скрипта.
Чтобы каждый раз не копипастить результат форматирования, у shfmt есть ключ -w, указав его, результат сразу перезапишется в файл над которым проводятся эксперименты.
Какого-то жесткого кодстайла нет, всё настраивается через ключи, например можно указать количество пробелов и т.п. Закидываем в алиасы и пользуемся.
Я обычно использую shfmt для подготовки скриптов для публикации в публичные репозитории github. Чтобы оупенсорц гуру гавном не закидывали на этапе плохого форматирования.
По секрету скажу, что в личных проектах (да и не только) особо никто не придерживается какому-то определенному форматированию. Все пишут каккурица лапой нравится, главное чтобы это работало. Практика плохая, ну лучше плохо чем вообще никак. Да и девчонки плохих любят.
🐱 Страница проекта на github
Вечером про отладку или обфускацию скриптов поговорим. На связи!
tags: #linux #bash #utilites
—
💩 @bashdays
Это не очередной линтер (но то же умеет орать на ошибки), это утилита для форматирования и синтаксического анализа скриптов. Байда написана на golang и поддерживает оболочки POSIX, Bash и mksh. Так что утилита не ограничена одним лишь bash.
Ставится из пакетного менеджера
apt/yum install shfmt. Ну и запускается так же элементарно:shfmt script.shСкармливаем утилите свой прекрасный скрипт, а на экран выводится приятный глазу отформатированный результат. Ну либо не выводится, если встречаются какие-то логические ошибки. Короче утилита выкашивает весь ненужный трешак, но сохраняет
Чтобы каждый раз не копипастить результат форматирования, у shfmt есть ключ -w, указав его, результат сразу перезапишется в файл над которым проводятся эксперименты.
Какого-то жесткого кодстайла нет, всё настраивается через ключи, например можно указать количество пробелов и т.п. Закидываем в алиасы и пользуемся.
Я обычно использую shfmt для подготовки скриптов для публикации в публичные репозитории github. Чтобы оупенсорц гуру гавном не закидывали на этапе плохого форматирования.
По секрету скажу, что в личных проектах (да и не только) особо никто не придерживается какому-то определенному форматированию. Все пишут как
Вечером про отладку или обфускацию скриптов поговорим. На связи!
tags: #linux #bash #utilites
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍86 1
Ну чо, расчехляем strace и погнали ковыряться в кишках. Сегодня будем проводить эксперимент над утилитой mktemp, которая входит в состав пакета coreutils.
mktemp, создает временный файл (по умолчанию) или директорию и возвращает имя созданного файла. Я ее использую для хранения промежуточных данных, когда нужно создать какую-то рандомную папку или файл и положить туда какой-нибудь мусор.
Задача - понять что произойдет если временный файл или папка уже существует. Будет ли mktemp создавать папку или файл с другим именем и сколько раз она это будет делать.
Для начала надо узнать с помощью какого системного вызова создается файл, запускаем:
y = выводим пути привязанные к дескрипторам файла
f = мониторим форки процессов
Можно и без ключей запускать, я просто так привык. После запуска получаем длинную портянку. Мне интересна лишь концовка, а именно:
Меня интересует:
Дополнительно нужно выяснить с какого по счету системного вызова будем перехватывать и возвращать ошибку. Суть в том, что при запуске mktemp есть несколько вызовов openat. Их делает динамический загрузчик. Если их перехватить, то программа просто не запустится. Также нужно избавиться от нескольких вызовов openat которые совершает система языковых переводов. Для этого нужно установить значения переменной LC_ALL в POSIX.
Выводим все openat которые делает утилита:
Это твои личные файлы зашифровываются. Шутки за 300.
Короче дождались пока оно там просрется и выведет табличку с результатами. Смотрим в колонку errors для системного вызова в openat и видим число 238328.
Вот собственно столько раз утилита mktemp будет пытаться создать файл с новым именем, после того как системный вызов будет возвращать ошибку, означающую что файл существует. Получается количество попыток 62**3 = 238328.
Упрямая утилита! Эксперимент завершен, результат получен, мы молодцы!
На этом собственно все, немного сложновато, но очень интересно. Потыкай сам и всё станет еще более прозрачным. Давай пять, увидимся!
tags: #linux #debug #utilites
—
💩 @bashdays
mktemp, создает временный файл (по умолчанию) или директорию и возвращает имя созданного файла. Я ее использую для хранения промежуточных данных, когда нужно создать какую-то рандомную папку или файл и положить туда какой-нибудь мусор.
Задача - понять что произойдет если временный файл или папка уже существует. Будет ли mktemp создавать папку или файл с другим именем и сколько раз она это будет делать.
Для начала надо узнать с помощью какого системного вызова создается файл, запускаем:
strace -Yyf mktempY = выводим команды с привязкой к PIDs
y = выводим пути привязанные к дескрипторам файла
f = мониторим форки процессов
Можно и без ключей запускать, я просто так привык. После запуска получаем длинную портянку. Мне интересна лишь концовка, а именно:
openat(AT_FDCWD</root>, "/tmp/tmp.V0051oIfmC", O_RDWR|O_CREAT|O_EXCL, 0600) = 3</tmp/tmp.V0051oIfmC>Ага, отловили openat. Идем сюда читать список ошибок которые возвращает openat.
Меня интересует:
EEXIST pathname already exists and O_CREAT and O_EXCL were used.Если были заданы флаги O_CREAT и O_EXCL и файл существует, то возвращается ошибка EEXIST.
Дополнительно нужно выяснить с какого по счету системного вызова будем перехватывать и возвращать ошибку. Суть в том, что при запуске mktemp есть несколько вызовов openat. Их делает динамический загрузчик. Если их перехватить, то программа просто не запустится. Также нужно избавиться от нескольких вызовов openat которые совершает система языковых переводов. Для этого нужно установить значения переменной LC_ALL в POSIX.
Выводим все openat которые делает утилита:
LC_ALL=POSIX strace -Yyfe openat mktempУ меня получилось 4 строки:
openat(AT_FDCWD</root>, "/etc/ld.so.cache")Вызов создающий временный файл у меня по счету 4й. Выпускаем кракена:
openat(AT_FDCWD</root>, "/lib/x86_64-linux)
openat(AT_FDCWD</root>, "/dev/urandom")\
openat(AT_FDCWD</root>, "/tmp/tmp.eyg53MQ1c2")
LC_ALL=POSIX strace -YCyfe inject=openat:error=EEXIST:when=4+ mktempВот это поворот! Ждем какое-то время и наблюдаем, как на экране бежит какая-то дичь.
Короче дождались пока оно там просрется и выведет табличку с результатами. Смотрим в колонку errors для системного вызова в openat и видим число 238328.
Вот собственно столько раз утилита mktemp будет пытаться создать файл с новым именем, после того как системный вызов будет возвращать ошибку, означающую что файл существует. Получается количество попыток 62**3 = 238328.
Упрямая утилита! Эксперимент завершен, результат получен, мы молодцы!
На этом собственно все, немного сложновато, но очень интересно. Потыкай сам и всё станет еще более прозрачным. Давай пять, увидимся!
tags: #linux #debug #utilites
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍89
This media is not supported in your browser
VIEW IN TELEGRAM
Привет коллеги. Как-то нашел на просторах github, интересную утилиту под названием Kill Port. Утилита написана bash.
Kill Port - инструмент командной строки для уничтожения процесса, запущенного на определенном порту.
Ситуация. Запускаю я например какое-нибудь nodejs приложение или gunicorn, а оно начинает орать - а у тебя порт уже занят. Начинается беготня с выяснением, а кто это сделал?
Особенно актуально при локальной разработке, где-то в фоне что-то висит и радуется. Естественно никогда не можешь вспомнить, что нужно набрать в консоли, чтобы узнать, какой процесс занимает порт (конечно кроме 80 и 443, все и так знают что это nginx).
Лезешь в гугол, находишь в очередной раз lsof -i :3000, киляешь все это в надежде. И так далее.
Автор Kill Port видимо тоже исстрадался и изобрел свой осиновый кол. Суть утилиты простая, скармливаешь ей порт который нужно освободить, она находит все эти процессы и завершает их. На гифке это наглядно все представлено. Удобно!
Можно форкнуть проект и добавить туда известные процессы, тот же nginx и gunicorn, чтобы корректно их завершать, а не килить через -9 (SIGKILL). Хотя это лишнее. Kill Port работает из коробки, что еще нужно.
Есть нюанс при установке, там чет у него в инсталляторе напутано, поэтому просто клоним скрипт killport, кидаем в /usr/local/sbin с атрибутом +x.
Для macos, утилита тоже работает, ставится через brew install killport.
Killport может не завершить процесс в случае определенных процессов работающие на уровне ядра, к примеру nfs / portmapper / wireguard. К ним не прикреплен соответствующий PID, но это крайние случаи. Для большинства сценариев, Killport успешно прикончит процесс.
🐱 Страница проекта на github
tags: #linux #utilites
—
💩 @bashdays
Kill Port - инструмент командной строки для уничтожения процесса, запущенного на определенном порту.
Ситуация. Запускаю я например какое-нибудь nodejs приложение или gunicorn, а оно начинает орать - а у тебя порт уже занят. Начинается беготня с выяснением, а кто это сделал?
Особенно актуально при локальной разработке, где-то в фоне что-то висит и радуется. Естественно никогда не можешь вспомнить, что нужно набрать в консоли, чтобы узнать, какой процесс занимает порт (конечно кроме 80 и 443, все и так знают что это nginx).
Лезешь в гугол, находишь в очередной раз lsof -i :3000, киляешь все это в надежде. И так далее.
Автор Kill Port видимо тоже исстрадался и изобрел свой осиновый кол. Суть утилиты простая, скармливаешь ей порт который нужно освободить, она находит все эти процессы и завершает их. На гифке это наглядно все представлено. Удобно!
Можно форкнуть проект и добавить туда известные процессы, тот же nginx и gunicorn, чтобы корректно их завершать, а не килить через -9 (SIGKILL). Хотя это лишнее. Kill Port работает из коробки, что еще нужно.
Есть нюанс при установке, там чет у него в инсталляторе напутано, поэтому просто клоним скрипт killport, кидаем в /usr/local/sbin с атрибутом +x.
Для macos, утилита тоже работает, ставится через brew install killport.
Killport может не завершить процесс в случае определенных процессов работающие на уровне ядра, к примеру nfs / portmapper / wireguard. К ним не прикреплен соответствующий PID, но это крайние случаи. Для большинства сценариев, Killport успешно прикончит процесс.
tags: #linux #utilites
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍99
Эх суету красоту навести охота! Привет. С помощью чего можно сделать красивые диалоговые боксы в скриптах и утилитах? Много всяких есть штук, но мне больше всего зашло использовать whiptail.
А зачем вообще красивые диалоговые окна в консоли? Можно же через read в bash всё прекрасно запрашивать. Да! Справедливо! Но это скучно, гораздо интереснее получить какой-нибудь мало-мальски красивый и интуитивный интерфейс.
Например, когда ты устанавливаешь mysql, оно тебе выводить красивый инпут где нужно ввести root пароль. Либо устанавливаешь linux и нужно выбрать галочками, какие пакеты ты хочешь установить. Ну короче ты понял. Некий GUI.
Вот whiptail и позволяет сделать этот GUI с минимальными усилиями + интегрировать его в свои скрипты.
Устанавливается банально: apt/yum install whiptail, но обычно уже идет из коробки в дистрибутиве.
После установки, можно творить. Синтаксис очень простой:
Помимо инпута yes/no имеется ряд других опций:
msgbox - информативное окно с кнопкой OK
infobox - херня какая-то, мигает и закрывается
inputbox - поле для ввода текста
passwordbox - поле для ввода пароля, скрыт звездочками
textbox - выводит содержимое файла в окне
menu - реализация меню
checklist - чекбоксы
radiolist - радиобатоны
gauge - прогрессбар
В общем подойдет на все случаи жизни. Что интересно, можно реализовать неплохое меню, либо красиво отобразить на экране результат работы утилиты. Полет фантазии безграничный.
Теперь про то, как все это замешать в bash скрипты.
Логика простая. Если пользователь выбирает Yes, то whiptail вернет 1. Если No, то вернет 0. Если возникла ошибка, либо принудительное завершение, будет возвращен код -1.
Например:
Ну а как получать данные, которые ввели руками? А вот так:
лысого между ними введенные и выбранные переменные.
Реализация меню:
Перенаправление ввода-вывода stdin/stdout/stderr. Если коротко, без этого ничего не заработает. Скучная теория. В будущем расскажу про все эти перенаправления stdin/stdout/stderr на котиках. Пока просто делай как написано.
На закуску лови реализацию прогрессбара, тут хоть что-то происходит и движется:
💩 Картиночки собрал тут, чтобы визуально оценить масштабы всей этой суеты.
Если есть вопросы и предложения, задавай в комментариях. Давай, увидимся вечером, хорошего тебе дня!
tags: #linux #bash #utilites
—
💩 @bashdays
А зачем вообще красивые диалоговые окна в консоли? Можно же через read в bash всё прекрасно запрашивать. Да! Справедливо! Но это скучно, гораздо интереснее получить какой-нибудь мало-мальски красивый и интуитивный интерфейс.
Например, когда ты устанавливаешь mysql, оно тебе выводить красивый инпут где нужно ввести root пароль. Либо устанавливаешь linux и нужно выбрать галочками, какие пакеты ты хочешь установить. Ну короче ты понял. Некий GUI.
Вот whiptail и позволяет сделать этот GUI с минимальными усилиями + интегрировать его в свои скрипты.
Устанавливается банально: apt/yum install whiptail, но обычно уже идет из коробки в дистрибутиве.
После установки, можно творить. Синтаксис очень простой:
whiptail --yesno "читаешь @bashdays?" 10 50Откроется диалоговое окно с двумя кнопками yes/no, с текстом + высотой и длиной.
Помимо инпута yes/no имеется ряд других опций:
msgbox - информативное окно с кнопкой OK
infobox - херня какая-то, мигает и закрывается
inputbox - поле для ввода текста
passwordbox - поле для ввода пароля, скрыт звездочками
textbox - выводит содержимое файла в окне
menu - реализация меню
checklist - чекбоксы
radiolist - радиобатоны
gauge - прогрессбар
В общем подойдет на все случаи жизни. Что интересно, можно реализовать неплохое меню, либо красиво отобразить на экране результат работы утилиты. Полет фантазии безграничный.
Теперь про то, как все это замешать в bash скрипты.
Логика простая. Если пользователь выбирает Yes, то whiptail вернет 1. Если No, то вернет 0. Если возникла ошибка, либо принудительное завершение, будет возвращен код -1.
Например:
if (whiptail --yesno "Choose Yes or No" 10 60) thenДефолные кнопки Yes/No можно зареврайтить с помощью опций --yes-button и --no-button.
echo "You chose Yes. Exit status was $?"
else
echo "You chose No. Exit status was $?"
fi
whiptail --yes-button "Fuck" --no-button "Yeee" --yesno "What?" 10 60Теперь вместо Yes/No наблюдаем Fuck/Yeee.
Ну а как получать данные, которые ввели руками? А вот так:
NAME=$(whiptail --inputbox "What is your name?" 10 60 3>&1 1>&2 2>&3)На экран выведется, то что, ты введешь в инпуте. Таким образом можно дальше строить диалоговые боксы и гонять
exitstatus=$?
if [ $exitstatus = 0 ]; then
echo "Your name is:" $NAME
else
echo "You chose Cancel"
fi
Реализация меню:
OPTION=$(whiptail --menu "Choose" 15 60 2 "1" "Linux" "2" "Windows" 3>&1 1>&2 2>&3)В остальных случаях всё делается идентично. Но что такое 3>&1 1>&2 2>&3? Это магия и скучная теория.
exitstatus=$?
if [ $exitstatus = 0 ]; then
echo "Your chosen:" $OPTION
else
echo "You chose Cancel."
fi
Перенаправление ввода-вывода stdin/stdout/stderr. Если коротко, без этого ничего не заработает. Скучная теория. В будущем расскажу про все эти перенаправления stdin/stdout/stderr на котиках. Пока просто делай как написано.
На закуску лови реализацию прогрессбара, тут хоть что-то происходит и движется:
{
for ((i = 0 ; i <= 100 ; i+=20)); do
sleep 1
echo $i
done
} | whiptail --gauge "Loading..." 6 60 0
Основное рассмотрели. Можно брать и что-то уже клепать вменяемое. У whiptail есть аналог, называется dialog, посмотри, возможно он подойдет именно тебе, синтаксис похожий. Если есть вопросы и предложения, задавай в комментариях. Давай, увидимся вечером, хорошего тебе дня!
tags: #linux #bash #utilites
—
Please open Telegram to view this post
VIEW IN TELEGRAM
👍119