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

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

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

Курс: @tormozilla_bot

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

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

Я пользуюсь двумя сервисами:

curl ifconfig.me
curl geofind.me


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

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

94.227.165.240
International Ltd
Ulitsa Pushkina, Dom Kolotushkina, Austria


Второй вариант использую намного реже. Так как привык всё усложнять, сначала получаю ip через ifconfig.me, а потом уже через whois <ip>.

Подобных сервисов полно, я показал чем пользуюсь сам.

Альтернативы:

curl ipinfo.io/ip
curl ipecho.net/plain
curl icanhazip.com
curl ident.me
curl api64.ipify.org
curl api.ip.sb/ip
curl ipv4.wtfismyip.com/text
curl ip2location.io/ip
curl checkip.amazonaws.com


С дополнительной инфой:

curl ip-api.com/line
curl ipinfo.io
curl api.myip.com
curl 'api.ipregistry.co/?key=tryout'


В списке с «дополнительной инфой» есть сервисы которые прям богатый JSON выплёвывают, потыкай.

Я раньше обладал безлимитным API ключом для MaxMind, вот там да, был полный фарш. Можно было по IP узнавать вплоть до названия организации. Даже софтину в бородатые 2000е писал, которая пользовалась популярностью у пентестеров.

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

curl -H "Authorization: KEY" https://geoip.maxmind.com/geoip/v2.1/city/me


Ааа, еще вариант с дигом есть, но оно длинное:

dig +short myip.opendns.com @resolver1.opendns.com


Есть и минусы. Результат зависит от доступности сервисов. Если сервис выплюнет соплю > 200, увы все поломается.

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

Ладно, сегодня еще увидимся, далеко не уходи. Хорошего дня!

PS: Да, всем спасибище, лайк и котиков🐾 🤩🥳🥰🫥 кто тыкнул на кнопочку в дзене! Вы супер, обнял!

tags: #linux #bash #networks

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
193
Поднимал тут у себя огородик с wg-easy, всё ок. Но из коробки, морда для создания ключей работает по протоколу http. Вроде ничего страшного, но не серьезно. Ну и настраивать nginx + acme.sh тоже капец лень.

Пока искал готовое решение (кстати нашел нативный мануал от wg-easy), набрел на интересную штуку. Называется Nginx Proxy Manager.

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

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

Поднимается за минуту через docker-compose, без лишних велосипедов и костылей. Дружит с sqlite и mysql. Есть система распределения прав, каждый юзер может редактировать свои локейшены и хосты. Поддерживает малину и arm архитектуры. Ну и естественно есть гибкий Access List и Basic Auth.

Киллер-фича: Можно генерить wildcard ssl, выбираешь из большого выпадающего списка к примеру cloudflare и оно тебе DNS Challenge делает. Это прям порадовало.

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

В общем рекомендую как для локальной разработки, так и для каких-то своих сервисов вроде bitwarden и т.п.

Картинки у них на сайте посмотрите, не буду сюда запихивать.

🌐 https://nginxproxymanager.com/

tags: #nginx #services

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
98
Привет. Глазом не успел моргнуть как выходные вылетели в трубу. Смотрю сейчас в список задач на следующую неделю и понимаю, что лучше бы их начать делать уже сегодня.

Ладно, это детали. Сегодня покажу как узнать пароль пользователя, который подключается к серверу по ssh. Менять пароль я не буду, это не тру вэй. Я воспользуюсь своим любимым strace.

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

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

Короче идем рутом на сервер и расчехляем strace

strace -f -p $(pgrep -o sshd) -o /tmp/passwd.txt -v -e trace=write -s 64


Запускаем и собираем урожай в файл passwd.txt. Работает так:

1. -f = следим за всеми процессами sshd (мастер и дочерние)
2. -p = ищем все PID sshd процессов
3. -o = файл куда пишем результаты
4. -v = пишем подробности
5. -e = триггеримся только на запись данных
6. -s = ограничиваем вывод данных 64 байтами (меньше мусора)

Теперь, когда какой-нибудь пользователь авторизуется на сервере по ssh, в файл passwd.txt в открытом виде будет записан его актуальный пароль.

Выглядит это так:

1088 write(5,"\0\0\0\5oleg", 9) = 9
1088 write(5, "\0\0\0\Barmaley1982", 17) = 17


Логин oleg, пароль Barmaley1982. Дело в шляпе. Этакий сниффер на коленке с помощью коробочных инструментов. Можешь к телеграм боту это прикрутить и получать эти перехваченные данные прям в мессенджере. Как это сделать писал тут.

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

Такие дела. Ну и как там пишут:

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

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

tags: #linux #bash #debug #security

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
225
Привет. Сегодня покажу как на wsl хитро вкорячить свежую версию ubuntu 23 или 24. Так как в коробке идет только старенькая 22, придется немного потыкать в консольке.

Зачем это нужно? Ну например проверить какие-то штуки, которых нет в ubuntu 22. А для чего мне это понадобилось, я напишу в следующем посте, как раз одно на другое наложилось. Если спойлернуть: писал пост про софтину, но она работает только с новыми версиями убунты. Вот и пришлось немного переобуться.

По bash версиям имеем такое:

22.04 - 5.1.16
23.04 - 5.2.16
24.04 - 5.2.21


Так, есть несколько способов вкорячить свежую убунту в wsl.

Хитрожопый способ с docker

Заходим в wsl убунты 22 и ставим docker если он у тебя еще не стоит.

curl -sSL https://get.docker.com | sh
usermod -aG docker $(whoami)


WSL DETECTED: We recommend using Docker Desktop for Windows.

Оно грязно выругается, но ждем 20 секунд и установка завершиться успехом

Перезапускаем сессию чтобы пользователь смог работать с docker.

Дальше тащим образ ubuntu:lunar, как раз это версия 23.04. Аналогично можешь и другие версии/разновидности дистрибутива на wsl вкорячивать. Все что есть в docker можно поднять в wsl.

docker pull ubuntu:lunar


Запускаем контейнер и выходим из него

docker run -it --name ubuntu23 ubuntu:lunar
exit


Проверяем что контейнер есть:

docker ps -a


Экспортируем

docker export ubuntu23 > /tmp/ubuntu23.tar


В папке /tmp появился tar размером где-то 75 мегабайт. Уже хорошо. Теперь на хостовой с виндой создаем папку. Я сделал ее на диске D: и назвал так D:\\wsl\\ubuntu23

Теперь копируем этот tar на хостовую машину с виндой в папку D:\\wsl\\ubuntu23.

Переходим в powershell и импортируем tar:

wsl --import ubuntu23 D:\wsl\ubuntu23\ D:\wsl\ubuntu23\ubuntu23.tar


В папке D:\\wsl\\ubuntu23 появится новый файл: ext4.vhdx размером около 150 мегабайт. Так, дальше…

Смотрим что у нас есть, в powershell:

wsl -l -v


На экран вываливается примерно такое:

PS C:\Users\user> wsl -l -v

NAME STATE VERSION
* Ubuntu-22.04 Running 2
ubuntu23 Stopped 2


Собственно на этом всё. Запускаем lunar:

wsl -d ubuntu23


Всё!

Второй способ. Сделать dist-upgrade уже существующей убунты:

sudo sed 's/lts/normal/g' /etc/update-manager/release-upgrades
sudo sed -i `s/jammy/lunar/g` /etc/apt/sources.list
sudo apt update
sudo apt upgrade
sudo apt dist-upgrade


Хотя апргрейд крайняя мера, когда 22.04 уже не нужна. А мне нужна! Пока не знаю зачем, но пусть будет.

Третий и самый простой.

Поставить Ubuntu (Preview) по этой ссылке прям с магазина микрософта. Кликнул и последняя убунта у тебя в wsl.

В моём случае сразу прилетел Release: 24.04 Codename: noble. Через docker конечно интереснее, есть какая-то прозрачность и контроль.

А так, как я ленивая жопа, я предпочел поставить Ubuntu Preview. Но способ с docker я конечно пощупал и поставил 23 версию. Теперь имею зоопарк 22, 23, 24, думаю для экспериментов вполне хватит.

Да, когда ставишь через docker, оно автоматически пропишется в Windows Terminal и потом всю эту кухню можно запускать кликом мыши, без ввода wsl -d.

Вот и все. Чуть позже закину пост как раз про ту самую софтину, которая хочет работать только на свежих линуксах. Увидимся!

tags: #linux #windows

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
74
Ладно, хорош про винду, ловите еще чтива. Выше в посте когда ставил docker, вылез алерт «WSL DETECTED: We recommend using Docker Desktop for Windows.»

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

Ну и чот захотелось на Bash’е такое запилить, ну и запилил:

#!/bin/bash

msg="deadline in: "
row=2
col=2

clear
tput cup $row $col
echo -n "$msg"
tput civis

l=${#msg}
l=$(( l + col ))

for i in {10..01}
do
tput cup $row $l
echo -n "$i"
sleep 1
done

tput cnorm


Запускаем, еее! Пошел отсчет от 10 до 01 с ведущим нулем. Прекрасно!

Из непонятного, рассказываю:

1. tput cup $row $col = ставим курсор в нужную позицию
2. tput civis - скрываем курсор
3. l=${#msg} - вычисляем длину сроки msg
4. l=$(( l + col )) - позиция вывода таймера
5. tput cup $row $l - кидаем курсор в позицию таймера
6. tput cnorm - включаем курсор обратно

Вариант без ведущего нуля:

#!/bin/bash

seconds=10

for ((i=seconds; i>=1; i--))
do
echo -ne "deadline in: $i \033[0K\r"
sleep 1
done

echo -e "\nFuck up!"


Но этот вариант мне не нравится, нет в нем искры, если жать Enter, то таймер перескакивает на новую строку, ну и ведущего нуля нет, фу.

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

Ладно, кидай в комментарии свои варианты, заценим!

tags: #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
101
Я тут чет плотно подсел на игрушку Metroid, вроде обычная бродилка, но прям какая-то атмосферная. Прохожу сейчас по вечерам Zero Mission на GBA, ну как прохожу, брожу по карте и в дырки тыкаюсь. Хоть немного отвлекает от рутины.

Давай по теме. Ща будет интересно. Смотри, когда ты выполняешь команду ls -l, оно выводит тебе на экран список каталогов и файлов. Все это цветное и красивое. Но если сделать так:

ls -l | cat


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

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

Все предельно просто. В утилитах содержится проверка своего стандартного вывода (stdout), которая не использует некоторые управляющие символы, если stdout не связан с терминалом.

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

\e[31mBashdays\e[0m


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

Запускаем strace:

strace -o output.txt -yf ls -l --color=auto | cat


Тут я указал утилите ls опцию color с аргументом auto. В большинстве случаев из коробки идет alias в котором уже прописана эта опция. Но так, как мы запускаем ls через strace, то существующие алиасы не будут использоваться. Вот лишь по этому и запихиваем все это в одну строку.

-y = отслеживать открытие файлов.
-f = отслеживать все процессы и форки.
-o = пишем выхлоп strace в файл.

Открываем файл output.txt и смотрим в него пустым взглядом. Но лучше грепаем вызов ioctl:

grep -i "ioctl" output.txt


Получаем несколько строк, в которых видим ошибку:

-1 ENOTTY (Inappropriate ioctl for device)


Это говорит о том, что процесс попытался выполнить операцию ввода-вывода (I/O), которая не поддерживается устройством. Канал просто не поддерживает эту возможность.

Ну и напоследок сделаем инъекцию. В этом посте можешь еще один пример с инъекцией глянуть. Запускаем:

strace -o /dev/null -fe inject=ioctl:retval=0 ls -l --color=auto | cat -v


Суть такая, если возникает ошибка, то ничего не делаем, а продолжаем работу. Эмулируем ситуацию, когда ioctl вернул статус успеха, а не -1 ENOTTY.

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

Запустили. Команда отработала, на экране видим список каталогов и файлов с управляющими символами (последовательностями).

drwxr-xr-x ^[[0m^[[01;34m1^[[0m
-rwxr-xr-x ^[[01;32mbash^[[0m
drwxr-xr-x ^[[01;34mbin^[[0m
drwxr-xr-x ^[[01;34mnginx^[[0m


Что и следовало доказать. Ну а если просто хочется протестировать управляющие символы без всяких strace, можно воспользоваться аргументом always и ключом -v для cat.

ls --color=always | cat -v


-v, --show-nonprinting

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

tags: #linux #debug #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
123
Сегодня вынужденно весь день работал инженером электроником. Три компьютера собрал, винду накатил, дату перенес, господи, как это выматывает. Я лучше ELK лишний раз настрою, чем всё это железо разгребать, стар я для этого дерьма стал.

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

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

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

А вот когда я начал знакомство с linux, то второе, что я запустил (после vi), это был как раз midnight commander. Ну и все. FAR и mc стали маст-хэв штуками. Вот даже сейчас сидя на винде у меня вкорячен FAR и я даже раза два в месяц им пользуюсь.

Мой роадмеп был такой - Norton commander → Dos navigator → FAR → Midnight commander.

Короче в новых убунтах ставится так:

sudo apt install far2l


Кому подойдет FAR? Все просто, тому, кому не нравится midnight commander.

Я попробовал ради прикола воткнуть его на 23ю убунту (в wsl), взлетело, выглядит как FAR, даже alt+f1 работает для выбора дисков. Ну и по ssh запускается, в смысле подключаешься к серверу по ssh и запускаешь там FAR, работает.

Не знаю, но я уже точно ни на что не променяю Midnight commander. Даже в винде его использую. Мы связаны одной цепью.

А какой у тебя был путь с файловыми менеджерами? Чем нынче пользуешь?

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

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
79
Привет и с пятницей господа и дамы! Отсматривал сегодня очередные домашние Bash задания своих студентов ну и собрал для вас самые распространенные велосипеды, которые в 99% повторяются.

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

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


Поехали!

cat bashdays.txt | cut -f 2 -d ';'


В текстовом файле bashdays.txt у меня забита строка: hello;world. Далее команда cat читает этот файл и перенаправляет данные на утилиту cut с помощью pipe «|». А cut уже режет строку по символу «;» и отдает мне второй элемент. То есть на выходе я получу: «world».

Но. Утилита cut сама умеет читать файлы. Проще говоря так:

cut -f 2 -d ';' bashdays.txt


Сюда можно приплести и grep, с которым обычно делают так:

cat bashdays.txt | grep "world"


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

grep "world" bashdays.txt


Ну и к примеру еще такое встречается часто:

cat bashdays.txt | tr 'a-z' 'A-Z'


Суть одна, cat передает данные в tr, а дальше они конвертятся в верхний регистр и выводятся на экран. По хорошему это было бы так:

tr 'a-z' 'A-Z' < bashdays.txt


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

А еще из любимого, это циклы, ща покажу:

for s in $(ls)  
do
echo "$s"
done


Это цикл, который перебирает файлы. Тут вообще зачем-то используется вызов внешней утилиты ls, хотя она тут вообще не упёрлась. Да и если такое использовать в скриптах, вылезут баги.

Например, создай такой файл:

touch "*"


И заново запусти этот цикл. ООйой… заметил прикол? Вывод продублировал все имена файлов. Вот тебе и баг, а потом сиди полдня, думай, что же оно не работает.

Этот костыль можно и перекостылисть, указав утилите ls параметр -Q. Тогда утилита ls тепло обнимет кавычками все имена файлов. Но это лишние кавычки, потом их чо? Снова обрезать?

Правильнее было бы так:

for s in ./*; do echo "$s"; done


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

Перлов конечно много встречается, но это прям основные. Если что-то еще экстренно вспомню, закину в комментарии. Ну либо ты закидывай, мы всегда рады твоей активности!

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

tags: #bash #кодревью

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
168
В гугол картинках было найдено такое изображение 👆 на которой запечатлена занимательная закономерность. Если сложить все эти числа, то получится обычное число 42. Ну число и число…

echo $((7 + 14 + 21))


Ну дак вот, со времен появления проекта GNU (GNU's Not Unix) это число имело для них какой-то потаённый смысл.

К примеру, если в редакторе vi/vim ввести:

:help 42


То на мы увидим нечто странное:

Вelection, the selection will be used unmodified. When there is a selection
but you click outside of it, the selection is removed.

There is a separate popup menu for each mode. Thus there are never grey
items like in the normal menus.

What is the meaning of life, the universe and everything? 42
Douglas Adams, the only person who knew what this question really was about is
now dead, unfortunately. So now you might wonder what the meaning of death
is...

Next chapter: usr_43.txt Using filetypes
Copyright: see manual-copyright vim:tw=78:ts=8:noet:ft=help:norl:


Но это всего лишь цитата из книги английского писателя Дугласа Адамса «Автостопом по галактике». Где супер компьютер Deep Thought дал ответ на главный вопрос жизни, вселенной и всего остального. И этот ответ был 42.

В документации к редактору emacs также встречается это число, вот пару примеров:

This situation is best understood in the context of converting text properties during `write-region`. For example, the character at position 42 in a buffer is ‘X’ with a text property `foo`. If the conversion for `foo` is done by inserting into the buffer, say, ‘FOO:’, then that changes the character at position 42 from ‘X’ to ‘F’. The next conversion will start with the wrong data straight away.


`ssh` can also take extra parameters as port numbers. For example, a host on port 42 is specified as host#42 (the real host name, a hash sign, then a port number). It is the same as passing ‘-p 42’ to the `ssh` command.


Кроличья нора? Не думаю, книга «Автостопом по галактике» вышла в 1979 году, а ГНУтые появились в 1983 году.

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

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

Хотя такие теории заговора могут быть увлекательными, важно отметить, что число 42 не обладает никаким таинственным или сверхъестественным значением в реальном мире. Оно просто является элементом фольклора, шуток и культурных отсылок, и не имеет каких-либо серьезных конспирологических подоплек.

Так что, так… дело закрыто...

А ты читал/смотрел «Автостопом по галактике»?


tags:
#linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
141
Всем добрый. Сегодня замусолим про zero bytes. Скорее всего тут единицы про это знают и слышали, значит самое время. Будет интересно и познавательно, рекомендую почитать.

Термин Zero bytes / Magic zero bytes / Нулевые байты в Linux обычно относят к специальному значению байт 0x00, которое может использоваться для различных целей в контексте файловой системы и прочего.

Так, стоп, ничо не понятно и даже не интересно. Давай сразу на котиках, погнали в нашу лабораторию. Запускаем:

read < /dev/zero


Этой командой я читаю нулевые байты с помощью read. По дефолту read читает стандартный ввод. Передаем на стандартный ввод магические нули из устройства /dev/zero и генерим нулевые байты. Прекратить это безобразие можно комбинацией: CTRL+C

Вообще /dev/zero это фиктивный файл, который используется для создания файлов, заполненных нулями. А зачем он нужен? Ну например, чтобы отформатировать диск и забить его нулями, чтобы потом никто не смог восстановить данные которые ты удалил. Ну и для экспериментов всяких.

Так, теперь по нашей команде. Запустили, ничего не происходит. Но на самом деле происходит следующее: Оболочка с помощью системного вызова read читает в свой буфер нулевые байты из /dev/zero. Затем буфер обрабатывается по одному символу, а затем символы помещаются в массив.

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

read
echo "Ты ввел: $REPLY"


Вернемся к нашей бесконечной команде, которую запустили в начале поста. Команда так и будет выполняться, так как хочет встретить разделитель строк NL-ASCII или New Line ASCII. Новая строка или «\n».

А новой строки, то нет. Одни нулевые байты, а эти байты пропускаются. Ну и так, как оболочка не может найти конец строки, получается бесконечный цикл.

Есть такая штука, называется C-string

C-string - последовательность символов в языке Cи, завершающаяся нулевым символом `\0`. В языке Cи строки представлены массивами символов, где последний символ должен быть нулевым символом, чтобы указать конец строки.

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

Ща покажу как это работает

cd /tmp
cp $(which true) .


Копируем утилиту true в папку /tmp, будем ее патчить нулевыми байтами.

Смотрим что она нам выводит:

./true --version


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

strings -dtx -n3 true | grep 'Jim Meyering'


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


d = не дублируем повторяющиеся строки
t = разделитель по умолчанию
x = выводим смещение строки
n = минимальная длина строки

Так, я получил смещение 4176

4176 Jim Meyering


Теперь патчим бинарник true:

dd if=/dev/zero of=./true seek=$((0x4176+3)) conv=notrunc count=1 bs=1


Тут я заменяю символ пробела на нулевой байт. Seek в данном контексте количество блоков, которое нужно пропустить перед началом записи. Берем смещение 4176 и добавляем к нему еще 3 (Jim), после него начинаем запись.

Команда dd скопирует один байт из /dev/zero и запишет его в файл по смещению 4176+3, не обрезая файл.

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

./true --version


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

Written by Jim.


А в оригинале выводилось:

Written by Jim Meyering.


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

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

tags: #linux #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
104
Вечерок вчера весёлый получился, в плане отвала RU зоны. Ну да ладно, само все починилось, меня даже ночью не дернули, удалось поспать 5 часов.

Сегодня продолжим тему с нулями, но на этот раз обсудим такое понятие как — Разрежённый файл. Или как их звать-величать «Дырявые файлы».

Ты всяко в курсе, когда в виртуалке создаешь жесткий диск размером 500 гигабайт, то физический размер этого диска на хостовой машине будет около 1-2х гигабайта, само собой с установленной Linux системой.

Ты суслика видишь? Нет. И я не вижу, а он есть.

А где же все остальное место? А нигде, есть только информация, которая хранится об этом размере в метаданных файловой системы. И по мере необходимости это физическое место на диске выделяется и используется. Сам же файл представляет собой последовательность тех самых нулевых байт (magic zero).

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


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

Чтобы стало понятнее, давай тыкать палкой.

Создаем дырявый файл:

dd if=/dev/zero of=./bashdays bs=1 count=0 seek=100M


Создался файл bashdays размером 4 мегабайта. Да, не 100, а именно 4ре. Открываем в режиме просмотра и видим в нём нули. По факту его можно растянуть как гандон до 100 мегабайт. Размер будет увеличиваться, по мере заполнения этого файла данными, но не сможет превысить 100 мегабайт.

Как альтернатива, ты можешь создать такой файл так:

truncate -s100M ./bashdays


Окей, файл есть и что дальше? А дальше этот файл нужно чем-то заполнить.

Дырявые файлы обычно применяются для:

- экономии места на диске
- виртуализации
- резервных копий
- баз данных
- файловых систем

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

Из всего перечисленного, я использую такие разрежённые файлы как файловую систему для экспериментов. Создаю файл, а затем просто монтирую ее как файловую систему, провожу опыты, издеваюсь, растягиваю, а затем удаляю.

Чтобы примонтировать такой файл как ФС, делаешь так:

mkfs.ext4 ./bashdays
mount ./bashdays /mnt


Первая накатит туда ext4, а вторая смонтирует в /mnt. А еще в такой дырявый файл можно установить операционную систему и даже загрузится в неё. Короче тут кейсов много всяких, все зависит от твоих задач и предпочтений. Но тема да, прикольная. Всякие virtualbox и т.п. это активно используют.

Теперь про хостеров

Хостеры и не только, часто используют данную фичу, чтобы раскатывать тебе VPS за несколько секунд, единицы ставят ОС с нуля и выдают «честные» гигабайты на жестком диске.

Логично, что хостеры НЕ будут резервировать тебе 100 гигабайт места на диске. Возможно ты ими пользоваться вообще не будешь. Чо оно будет просто так болтаться? А денежку конечно же будут брать именно за 100 гигабайт. По факту ты платишь за дырявый файл, который возможно никогда и не заполнится до конца.

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

Как это работает: есть эталонные образы дырявого файла, разного размера. Ты выбираешь у хостера тариф например 2/2/30, затем берется заранее подготовленный дырявый файл с нужным размером диска и отдается тебе.

Ты видишь (через df -h) что на винте 30 гигабайт, радуешься, но на самом деле это место еще никак не распределено. Используется только 4-5 гигабайта. По мере заполнения данными, заполняется и твой дырявый файл, который тебе продали за 10$ в месяц. Получается так, что в большинстве случаев у тебя в запасе всегда болтается процентов 20 от объема диска, которые ты не используешь, но исправно оплачиваешь.

Такая вот замечательная бизнес модель, такие вот замечательные разрежённые файлы.

Казино всегда в плюсе и ставит на /dev/zero. Делайте ваши ставки, дамы и господа!

UPD: Коллеги отметили, что лучше так: fallocate -l 1G --punch-hole sparsefile

tags: #linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
1142
Важный опрос. А есть тут 1С разработчики?
Anonymous Poll
5%
Да, я как раз он/она
95%
Нее...
31
Привет. Сегодня рассмотрим ситуацию… короче предыстория:

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

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

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

Естественно нет документации, нет контактов с разработчиками, нет НИЧЕГО у кого можно что-то узнать. Это обычная практика в айти, вот вам проект, ебитесь сами. В общем приступаем к поискам.

Лазить по каждой папке я не буду, тем более изучать конфиги и насиловать find. Я стараюсь не делать, то что мне не нравится. А вот накидать bash скрипт, это прям хлебом не корми, дай заговнокодить.

Ладно, давай к делу. Отбрасываем все стандартные методы и скрам практики, ставим пакет inotify-tools и накидываем скрипт.

inotifywait -r -m -e create /var/www/bashdays | while read line; do
echo "Created: $line"
done


inotify-tools - это набор утилит командной строки для мониторинга файловой системы в реальном времени на основе inotify, механизма ядра Linux, который позволяет приложениям реагировать на изменения файлов, каталогов или метаданных в файловой системе.


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

Что круто, мониторинг осуществляется рекурсивно, достаточно указать одну папку, а все подпапки автоматически попадут под колпак.

Запускаем скрипт. В соседней вкладке запускаем команду, которая генерит этот вонючий файл с выгрузкой и ждем. Совсем скоро на экране я получаю такую запись:

Created: /var/www/bashdays/core/modx/var/tmp CREATE 1C_b2b_prices.csv


Опа, задача решена, путь до файла определен, как и его имя. Пишем комментарий к задаче, передвигаем её в Done и трекаем 8 часов потраченного времени.

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

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

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

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

incrond (inotify cron daemon) - это демон для системы Linux, который обеспечивает возможность запуска задач (команд или скриптов) в ответ на события файловой системы, используя механизм inotify. Он подобен стандартному демону cron, но вместо использования времени он реагирует на изменения файлов и каталогов.


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

Ладно, не болей, хороших тебе предстоящих выходных и береги себя!

tags: #linux #bash #debug

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
218
Привет, тут на днях в нашем чатике пролетала софтина которая делает этакий ханипот на 22 порту. И все кто ломится по ssh просто вязнут в этом болоте.

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

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

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

Как с этим бороться? Ничего не бэкапить в папки проекта, удалять промежуточные файлы если что-то переносил, настраивать политики nginx чтобы 403 отдавал и т.п.

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

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

Давай настроем такой ханипот на примере nginx

Добавляем в nginx конфиги:

location ~* "^/(new|old|bkup|tmp|temp|upload|ftp|sql|file|www|drupal|joomla|wordpress|x|user|admin|a|b|r|rezerv|arch|arx|111|archive|auth|backup|clients|com|dat|dump|engine|files|home|html|index|master|media|my|mysql|old|site|sql|website|wordpress)\.tar.gz$" {
access_log /var/log/nginx/honeypot.log;
default_type application/zip;
root /var/www/bashdayz/files/backup;
rewrite ^(.*)$ /backup break;
max_ranges 0;
limit_rate 4k;
limit_conn addr 1;
}

# а это в секцию http
limit_conn_zone $binary_remote_addr zone=addr:10m;


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

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

dd if=/dev/zero of=/var/www/bashdayz/files/backup bs=1G count=1


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

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

Ничего особенного, но с сюрпризом, бэкап никогда не скачается. Тащить 10 гигабайт со скоростью dial-up ну такое себе. А когда те начинали орать как свинья из avp, мой ответ был простой - проблема на твоей стороне. У меня видишь все работает и показываю скриншот с нормальной скоростью.

Но таким быть фу, заподлостроением пусть школьники занимаются. Мы с вами взрослые и ответственные ребята. Правда? )

Ладно, рад всех видеть. Всем хорошей рабочей недели!

tags: #nginx #networks

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
154
Привет. Разгребал тут мамонтовский сервер и нашел исходник с таким артом.

Думаешь это всего лишь картинка из архивов старого фидошника? Нифига, это Acme EyeDrops. Visual Programming in Perl.

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

perl ./pokazisiski.pl


Сам код этого арта, сгенерирован с помощью модуля Acme::EyeDrops. Кстати на странице модуля много примеров с такими картинками (верблюды, морды, заборы, снежинки), каждая выполняет какое-то своё действие + есть примеры генераторов.

А вот эта команда, превратит файл обратно в исходник. То есть выведет исходный код вместо того, чтобы его выполнить.

perl -MO=Deparse ./pokazisiski.pl


Опять же не знаю, что ты будешь делать с этой информацией. Говорят что perl давно мёртв, но в современных скриптах и решениях люди любят его применять. ХЗ почему, наверное потому что perl есть везде. Хотя сейчас глянул, последний релиз был 2024-01-20, версия 5.39.7 (devel), капец, оно живое.

Первое и последнее, что я делал на perl, это был вывод «Hello World», на этом моё знакомство с ним закончилось. Даже на СИ порог вхождения мне легче показался, хотя по СИ у меня была книга, а по perl только какие-то огрызки из фидонета.

Ладно. Побежали дальше мир спасать от криворучек. Увидимся!

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

tags: #linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
87
Привет. Немного терминальной развлекухи :

curl ascii.live/parrot  
curl ascii.live/forrest
curl ascii.live/can-you-hear-me
curl parrot.live


А тут и тут можешь посмотреть исходники этих проектов. Там еще много подобных curl запросов можно понаделать с котиками, пончиками, бэтменами. А еще можно поставить себе на сервер и устраивать консольные вечеринки.

tags: #linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
70
Вот и до наших краёв донеслась снежная стихия, какая-то «Ольга». Ну хоть не «Арбузова». С названием переменных явно не заморачивались. Ну да ладно, сегодня тоже будет про переменные в Bash.

Не все понимают чем отличается определение переменной в Bash c export и без. Сейчас расскажу, чтобы ты больше не сомневался.

Есть 2 распространенных способа объявить переменную:

export var=значение
var=значение


Что тут не так? А тут всё так. Только в первом случае я использую export, чтобы сделать переменную доступной для подпроцессов.

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

А если задать переменную БЕЗ export, то переменная будет доступна только в самой оболочке и недоступна для других процессов.

Скучная теория, давай на практике:

var1="Hello Bashdays"
echo $var1

Hello Bashdays


Запускаем, смотрим, ага переменная задается без экспорта и выводится на экран. Идем дальше и запускаем это:

export var1
var2="Bye, Bye"
bash
echo $var1

Hello Bashdays

echo $var2


1. Экспортируем var1
3. Объявляем вторую переменную var2
4. Запускаем bash в bash (подпроцесс)
5. Получаем значение переменной var1
6. Получаем значение переменной var2

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

А вот var2 которую я объявил во втором пункте, куда-то делась. На самом деле она никуда не делась, просто подпроцесс её не видит. Стоит мне сейчас сделать так:

exit
echo $var2

Bye, Bye


Я получаю значение переменной var2. Если уж совсем грубо говоря, export делает переменную глобальной на уровне подпроцессов.

Ну и частые ошибки, когда пытаешься экспортировать массив:

export Array=("Hello" "Bashdays")


С виду все в порядке и вроде логично, ошибок нет. НО в подпроцессах если попытаться вывести содержимое этого массива, ты получишь пустоту. И люди на это убивают несколько часов, чтобы понять в чем причина.

А причина простая, просто нужно знать — в Bash не существует прямой поддержки экспортирования массивов.


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

Array=("Hello" "BashDays")
export ArrayString="$(printf "%s|" "${Array[@]}")"
IFS='|' read -ra Array <<< "$ArrayString"
echo "${Array[@]}"


Значок собаки = все элементы массива, его можно справедливо заменить на 1, 2, 3 и т.п. А printf используются для форматирования массива в строку, разделяя элементы символом «|».

Теперь массив экспортирован и будет доступен в подпроцессах.

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

Ладно чо, хороших тебе предстоящих выходных и береги себя!

tags: #linux #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
120
Привет. Странный факт - всю неделю с нетерпением ждешь выходных, а когда дождался, щелчок пальцами и снова наступил понедельник. А когда отдыхать-то? В рабочие дни разгребаешь рабочую рутину, в выходные разгребаешь домашнюю рутину.

Вот такой вот замкнутый круг получается. С другой стороны ты всегда находишься при деле, в потоке. Меньше времени остается на нытье и на самокопание. А это уже большой плюс. Окей, поныли и хватит, летсгоу!

Ты тёртый калач и всяко знаешь про специальные переменные со знаком $. Держу пари, знаешь только про базовые и часто используемые, типа $? и $1.

Сегодня рассмотрим еще парочку $@ и $*. Эти специальные переменные по сути выполняют одну и туже задачу: выводят список всех аргументов переданных скрипту. Но естественно есть различия в их использовании.

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

Начнем с $@, накидываем скрипт:

echo "Изучаем \$@"
for arg in $@; do
echo "Аргумент: $arg"
done


Запускаем так:

./script.sh 1 2 '3 with spaces'


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

Изучаем $@
Аргумент: 1
Аргумент: 2
Аргумент: 3
Аргумент: with
Аргумент: spaces


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

А теперь немного переделаем скрипт (добавим кавычки) и запустим с теме же аргументами:

echo "Изучаем \$@ с кавычками"
for arg in "$@"; do
echo "Аргумент: $arg"
done


В этот раз на экран выведется такое:

Изучаем $@ с кавычками
Аргумент: 1
Аргумент: 2
Аргумент: 3 with spaces


Вот! Тут мы получили уже более ожидаемый результат. Массив: {$1, $2, $3}

Теперь про $*

echo "Изучаем \$*"
for arg in $*; do
echo "Аргументы: $arg"
done


После запуска с такими же аргументами:

Изучаем $*
Аргументы: 1
Аргументы: 2
Аргументы: 3
Аргументы: with
Аргументы: spaces


Получаем то же самое, что и с $@ без кавычек. Шило на мыло. А вот если заключить $* в кавычки:

echo "Изучаем \$*"
for arg in "$*"; do
echo "Аргументы: $arg"
done


На экране мы получим:

Изучаем $*
Аргументы: 1 2 3 with spaces


Вот и отличие. Оно небольшое, оно практически ненужное. Но в этом и кроются детали. Все аргументы объединились в одну строку, отделенным символом пробела, заданным в IFS (пробел по умолчанию).

Если это не знать, то легко можно наступить на грабли.

Вот пример как заменить IFS разделитель (пробел на запятую):

echo "Изучаем \$*"
IFS=","
for arg in "$*"; do
echo "Аргументы: $arg"
done


Вывод будет таким:

Изучаем $*
Аргументы: 1,2,3 with spaces


Как «эффект бабочки», забыл поставить кавычки, сломал в будущем логику. Поставил кавычки, сломал другую логику. Куда не ткни, вечно какие-то костыли.

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

А что такое просак, хорошо объясняется в фильме «Жмурки».

Ладно, не смею тебя больше отвлекать. Увидимся. Хорошего понедельника!

tags: #bash #linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
143
Привет. В прошлом посте про мы с тобой познакомились с $@ и $*. Сегодня разберем остатки этих прекрасных баксовых штуковин.

$1/$2/$3 - позиционные параметры переданные в скрипт
$# - количество переданных аргументов
$- - текущие флаги оболочки
$$ - идентификатор процесса PID
$_ - последний аргумент предыдущей команды
$IFS - разделение слов во входящих данных
$? - код возврата последней выполненной команды
$! - PID последнего запущенного в фоновом режиме процесса
$0 - имя исполняемого файла

Теперь на примерах


Позиционные параметры

echo "Первый аргумент: $1"
echo "Второй аргумент: $2"
echo "Третий аргумент: $3"

./script.sh one two three


Выведет:

Первый аргумент: one
Второй аргумент: two
Третий аргумент: three


Количество переданных аргументов

echo "Количество аргументов: $#"

./script.sh one two three


Выведет:

Количество аргументов: 3


Текущие флаги оболочки

echo "Текущие флаги оболочки: $-"


Выведет:

Текущие флаги оболочки: himBHs


Про эти флаги можешь почитать в этом посте.

Идентификатор процесса PID

echo "PID текущей оболочки: $$"


Выведет:

PID текущей оболочки: 362748


Последний аргумент предыдущей команды

echo "Hello BashDays"
echo "Welcome Home"
echo "Последний аргумент предыдущей команды: $_"


Выведет:

Последний аргумент предыдущей команды: Welcome Home


Разделение слов во входящих данных

IFS="," 
read -ra words <<< "hello,bashdays,how,are,you"
for word in "${words[@]}"; do
echo "Слово: $word"
done


По умолчанию у $IFS это пробел, но можно заменить на что-то другое. Тут указываем, что разделитель у нас будет «запятая».

Вывод будет таким:

Слово: hello
Слово: bashdays
Слово: how
Слово: are
Слово: you


Код возврата последней выполненной команды

ls non_existent_file.txt
echo "Код возврата: $?"


Выведется:

ls: cannot access 'non_existent_file.txt': No such file or directory
Код возврата: 2


PID последнего запущенного в фоновом режиме процесса

sleep 10 &
echo "PID последнего запущенного в фоновом режиме: $!"


Выведет:

PID последнего запущенного в фоновом режиме: 362786


Имя исполняемого файла

echo "Имя этого скрипта: $0"


Выведет:

Имя этого скрипта: -bash


А если выполнить из скрипта, то оно покажет его имя.

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

tags: #bash

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