Представь, что у тебя есть две коробки. На одной написано «хуи дрочёны», а на другой «пики точены».
Ты хочешь проверить:
ㅤ
— В первой коробке хуи?
— Во второй коробке пики?
Если оба условия верны, ты говоришь — заебись!.
Бэд практика:
Тут
Бест-практика:
Разделяем на две проверки:
Сначала проверяется первое условие, затем второе.
Если оба верны — команда выполнится.
Либо делаем конкретно под Bash:
Здесь можно использовать
Выводы:
Если используешь
Если
tags: #bash #badpractices #bestpractices
—
🔔 @bashdays➡️ @gitgate
Ты хочешь проверить:
ㅤ
— В первой коробке хуи?
— Во второй коробке пики?
Если оба условия верны, ты говоришь — заебись!.
Бэд практика:
[ "хуи" = "коробка1" -a "пики" = "коробка2" ]
Тут
-a (И) считается устаревшим и в некоторых случаях это работать не будет. Так что если такое видишь или пишешь, сразу сноси, это хуйня!Одна из проблем с [ A = B -a C = D ] (или -o) в том, что POSIX не определяет, как должна работать команда [ ... ], если у неё больше 4 аргументов.
Бест-практика:
Разделяем на две проверки:
[ "коробка1" = "хуи" ] && [ "коробка2" = "пики" ]
Сначала проверяется первое условие, затем второе.
Если оба верны — команда выполнится.
Либо делаем конкретно под Bash:
[[ "коробка1" = "хуи" && "коробка2" = "пики" ]]
Здесь можно использовать
&&, всё будет работать правильно.Выводы:
Если используешь
[ ... ], то делай две отдельные проверки.Если
[[ ... ]], то можно писать всё внутри.tags: #bash #badpractices #bestpractices
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Если написать так
ㅤ
Двойные скобки
➡️ Бест-практика
А если хочется прям строго соответствовать POSIX, делай так:
Теперь давай разберемся почему с
Символ
В
Еще пример:
Если
Код выше проверяет, является ли переменная
Выводы: для работы с числами используем
tags: #bash #badpractices #bestpractices
—
🔔 @bashdays➡️ @gitgate
[[ $foo > 7 ]], то далеко не факт что это правильно отработает.ㅤ
Двойные скобки
[[ ... ]] в Bash предназначен для проверки условий, но не для работы с числами. Для чисел лучше хуячить (( ... )).(( foo > 7 ))
А если хочется прям строго соответствовать POSIX, делай так:
[ "$foo" -gt 7 ]
Теперь давай разберемся почему с
[[ $foo > 7 ]] словишь ошибку.Символ
> в [[ ... ]] сравнивает строки, а не числа. Например, "10" < "7", потому что 1 идёт раньше 7 в алфавите.В
[...] символ > вообще означает «перенаправление вывода», и создаст файл с именем 7 в текущей папке.Еще пример:
case $foo in
("" | *[!0123456789]*) echo "Ошибка: foo не число!" && exit 1 ;;
*) [ "$foo" -gt 7 ] ;;
esac
Если
$foo содержит что-то вроде $(rm -rf /), то при определённых условиях это может привести к пиздецу. Поэтому перед проверкой лучше убедиться, что $foo — это число.Код выше проверяет, является ли переменная
$foo числом, и если да, сравнивает её с 7.case $foo in — конструкция для проверки значений переменной $foo по шаблонам.
"" — пустая строка (если $foo пустое).
("" | *[!0123456789]*) — строка, содержащая хотя бы один символ, который не цифра (например, abc, 12a3).
Если условие выполняется, выводится сообщение "Ошибка: foo не число!", и скрипт завершает работу с кодом 1 (exit 1).
* — означает «всё остальное» (то есть, если $foo не попал под первый шаблон).
[ "$foo" -gt 7 ] — проверяет, больше ли $foo чем 7.
Выводы: для работы с числами используем
(( ... )) или [ "$foo" -gt 7 ], а переменные перед проверкой лучше очищать от лишних символов.tags: #bash #badpractices #bestpractices
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Продолжаем делать правильно.
ㅤ
Этот код выглядит вполне нормально:
Он считает, сколько строк в файле
Здесь главная проблема — переменная
Если простым языком: Каждая часть, разделённая
Этот код вернет 0, несмотря на
Как быть?
Первый вариант:
Эта штука говорит интерпретатору — что последний элемент конвейера будет выполнен в окружении текущей оболочки.
Второй вариант:
Вообще избавиться от
Можно еще наколхозить и передавать значения через временный файл, но это прям пиздец шляпа и костыль.
Выводы
Нужно просто посчитать строки:
Нужно обрабатывать строки:
Хочешь использовать pipe:
Вот и вся наука.
tags: #bash #badpractices #bestpractices
—
🔔 @bashdays➡️ @gitgate
ㅤ
Этот код выглядит вполне нормально:
grep foo bar.txt | while read -r; do ((count++)); done
Он считает, сколько строк в файле
bar.txt содержат слово foo.Здесь главная проблема — переменная
count не изменится вне цикла while, потому что в Bash каждая команда в пайплайне (|) запускается в отдельной оболочке (subshell). То есть count++ происходит «внутри», и снаружи этого не видно.Если простым языком: Каждая часть, разделённая
|, запускается в отдельной «коробке» (subshell). То есть while работает внутри своей коробки. B всё что там происходит, не видно снаружи.Некоторые оболочки ksh93 или Bash с включённой настройкой shopt -s lastpipe работают по-другому — цикл выполняется в той же оболочке, и тогда count изменится.
count=0
echo -e "one\ntwo\nthree" | while read line; do ((count++)); done
echo $count
Этот код вернет 0, несмотря на
count++, а вот например в zsh вернется 3.Как быть?
Первый вариант:
shopt -s lastpipe
Эта штука говорит интерпретатору — что последний элемент конвейера будет выполнен в окружении текущей оболочки.
Второй вариант:
Вообще избавиться от
while и всё сделать через grep:count=$(grep -c foo bar)
echo $count
Можно еще наколхозить и передавать значения через временный файл, но это прям пиздец шляпа и костыль.
Выводы
Нужно просто посчитать строки:
count=$(grep -c foo bar)
Нужно обрабатывать строки:
while read line; do ...; done < bar
Хочешь использовать pipe:
shopt -s lastpipe
Вот и вся наука.
tags: #bash #badpractices #bestpractices
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Вот те на!
Большинство думает, что
ㅤ
В Bash
Скобка
Команда выше напечатает
Теперь о главном
Если хочешь использовать
Плохая практика:
Внутри
Хорошая практика:
Если
И Всё работает как надо, без лишних скобок!
Выводы
Никогда не пиши
Пиши просто
tags: #bash #badpractices #bestpractices
—
🔔 @bashdays➡️ @gitgate
if [ false ]; then echo "HELP"; fi
Большинство думает, что
[ — это часть команды if как скобки в других языках программирования. Но нихуя!ㅤ
В Bash
if просто запускает команду. Команда [ ... ] — это обычный бинарник, аналогично команде test, а не специальный синтаксис. Скобка
] нужна только для красоты и завершения команды [.Команда выше напечатает
HELP, потому что строка "false" — непустая, а значит, условие считается истинным.Теперь о главном
Если хочешь использовать
grep в if, не надо писать скобки!Плохая практика:
if [ grep -q "foo" myfile ]; then
echo "Найдено!"
fi
[... ] — ожидает условие, а не командуgrep — это команда, а не логическое выражениеВнутри
[ запускать команды нельзя — это приведёт к ошибкеХорошая практика:
if grep -q "foo" myfile; then
echo "Найдено!"
fi
if просто запускает grepЕсли
grep нашёл совпадение, он вернёт 0 (успех), и выполнится thenИ Всё работает как надо, без лишних скобок!
[ — это как калькулятор, а grep — это поиск. В калькуляторе искать бесполезно!Выводы
Никогда не пиши
if [ grep ... ] — это ошибка!Пиши просто
if grep ..., чтобы проверить результат команды.if работает с командами. [ — это тоже команда, но не синтаксис.tags: #bash #badpractices #bestpractices
—
Please open Telegram to view this post
VIEW IN TELEGRAM
2 83
Позволил себе пару дней ничего не делать, кроме конечно проверки LF домашек. Лежал, исследовал дырки в axiom verge, гулял. Мне понравилось!
ㅤ
Буду почаще практиковать. Но есть и жирный минус, сегодня пришлось себя прям заставлять что-то сделать по работе. К хорошему привыкаешь быстро.
Ладно, лирика. Давай дальше бест-практики тыкать.
Команда
Тут самое важно это — пробелы, про кавычки повторять не буду, ты это уже и так знаешь. Все уши тебе прожужал.
Неправильно:
1. Нельзя слеплять всё вместе. Это хуёва даже в плане кодстайла.
2. Нет пробела вокруг знака «=».
3. Аналогично, всё слеплено.
Правильный синтаксис:
или
Почему?
Потому что
Главное правило — всегда ставь пробелы между каждым элементом в условии.
tags: #bash #badpractices #bestpractices
—
🔔 @bashdays➡️ @gitgate
ㅤ
Буду почаще практиковать. Но есть и жирный минус, сегодня пришлось себя прям заставлять что-то сделать по работе. К хорошему привыкаешь быстро.
Ладно, лирика. Давай дальше бест-практики тыкать.
Команда
if [ bar = "$foo" ]; проверяет, равны ли два значения.Тут самое важно это — пробелы, про кавычки повторять не буду, ты это уже и так знаешь. Все уши тебе прожужал.
Неправильно:
[bar="$foo"]
[ bar="$foo" ]
[[bar="$foo"]]
1. Нельзя слеплять всё вместе. Это хуёва даже в плане кодстайла.
2. Нет пробела вокруг знака «=».
3. Аналогично, всё слеплено.
Правильный синтаксис:
if [ bar = "$foo" ]; then
или
if [[ bar = "$foo" ]]; then
Почему?
Потому что
[, =, ] это отдельные символы, первая скобка вообще команда test. А если ты все слепляешь, Bash посчитает тебя долбаёбом и отправит в пешее эротическое.Главное правило — всегда ставь пробелы между каждым элементом в условии.
tags: #bash #badpractices #bestpractices
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Бебебед практики bash, продолжаем.
Нельзя просто так взять условие из языка «Сиськи» и заменить его на квадратные скобки.
Сколько не повторяй, один хер делают неправильно.
Команда
Хуёвая практика:
В этом примере сначала проверяется
Если же
Бест-практика! Зырь!
Делаем двойные скобки. Двойные скобки умеют работать с
Внутри неё можно использовать логические операторы
Рассмотрим пример:
Для тупых Кто до сих пор не понял:
Представь, что ты говоришь своей бабушке: Если я убрал в комнате И сделал уроки, я могу поиграть в девопс-инженера.
Ну так вот:
Вот и вся наука. Изучай!
🛠 #bash #badpractices #bestpractices
—
✅ @bashdays / @linuxfactory / @blog
Нельзя просто так взять условие из языка «Сиськи» и заменить его на квадратные скобки.
Сколько не повторяй, один хер делают неправильно.
Команда
[ — это не просто скобка, а отдельная команда. Она проверяет, пиздеж ли что-то или нет.Хуёвая практика:
if [ a = b ] && [ c = d ]; then
...
fi
В этом примере сначала проверяется
a = b, если это пиздёж — дальше ничего не выполняется.Если же
a = b НЕ пиздёж — тогда проверяется c = d. И если c = d НЕ пиздёж, то выполняется, то что внутри then.Проще по моему объяснить уже нереально. Сложно перепутать пизду с розеткой. Хотя… вечно путают.
Бест-практика! Зырь!
if [[ a = b && c = d ]]; then
...
fi
Делаем двойные скобки. Двойные скобки умеют работать с
&& внутри.[[ ... ]] — это специальная команда Bash, которая используется для проверки условий. Она умнее и безопаснее, чем обычная [ ... ].Внутри неё можно использовать логические операторы
&& (и) и || (или) без дополнительных скобок или дополнительных [.Рассмотрим пример:
a="hello"
b="hello"
c="bashdays"
d="bashdays"
if [[ $a = $b && $c = $d ]]; then
echo "Условия совпали!"
fi
1. Проверяет $a = $b → "hello" = "hello"? → Да.
2. Дальше && говорит: Если первое условие — НЕ пиздёж, идём ко второму.
3. Проверяет $c = $d → "bashdays" = "bashdays"? → Да.
4. Оба условия верны → выполняется команда echo.
[ — работает с одним условием за раз[[ — может работать с комбинированными условиями прямо внутри себя.Представь, что ты говоришь своей бабушке: Если я убрал в комнате И сделал уроки, я могу поиграть в девопс-инженера.
Ну так вот:
[[ ... ]] — это бабушка, которая за всю свою жизнь повидала много дерьма и вполне может понять твою сложную фразу: убрал И сделал уроки.[ ... ] — это твой младший брат, пиздюк еще не в состоянии воспринимать такие большие выпады и ему нужно говорить частями.«Сначала убрал?» — (ДА) Не пиздёж.
«Сделал уроки?» — (ДА) Не пиздеж.
«Ок, теперь я могу поиграть в девопс-инженера»
Вот и вся наука. Изучай!
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Короче блядь! Если ты хочешь сохранить то, что ввёл человек, в переменную с именем
ㅤ
Напиши так:
А если хочешь прикрыть своё очко от спецсимволов, делай так:
Вот так делать хуёва:
В этом случае
Как говорил мой техдир:
Делай правильно и твои руки никто не оторвёт и не пропьёт.
Для маленьких:
Представь, ты говоришь: «Дай хуй» — и тебе сразу дают хуй.
Всёж просто.😲
А теперь представь, что ты говоришь: «Дай $хуй».
Тут сначала дополнительно нужно спросить «А кто такой хуй?» — может, это Олег? И тогда тебе дадут Хуй Олега.
То есть, сначала нужно узнать, кто прячется под «хуем», а потом уже брать, чтобы не взять чужой «хуй».
Надеюсь ты понял. Изучай!
🛠 #bash #badpractices #bestpractices
—
✅ @bashdays / @linuxfactory / @blog
foo, то не нужно писать доллар ($) перед именем переменной.ㅤ
Напиши так:
read foo
А если хочешь прикрыть своё очко от спецсимволов, делай так:
IFS= read -r foo
Вот так делать хуёва:
read $foo
В этом случае
$foo — уже не имя переменной, а значение переменной foo. Как говорил мой техдир:
Рома, золотые у тебя руки. Оторвать бы их да пропить.
Делай правильно и твои руки никто не оторвёт и не пропьёт.
Для маленьких:
Представь, ты говоришь: «Дай хуй» — и тебе сразу дают хуй.
Всёж просто.
А теперь представь, что ты говоришь: «Дай $хуй».
Тут сначала дополнительно нужно спросить «А кто такой хуй?» — может, это Олег? И тогда тебе дадут Хуй Олега.
То есть, сначала нужно узнать, кто прячется под «хуем», а потом уже брать, чтобы не взять чужой «хуй».
Надеюсь ты понял. Изучай!
—
Please open Telegram to view this post
VIEW IN TELEGRAM
3 70
Всё тебе, блядь, смехуюшечки да пиздахаханьки.
ㅤ
Создаём файл:
Внутри получаем:
И применяем бэд-практику:
Эта команда читает файл
Что тут не так?
А всё! В лучшем случае получишь хуем по лбу и примеришь золотой пизды колпак. Эта команда испортит файл. Низя так делать! Всё проебёшь!
После этой команды файл
А теперь делаем правильно!
Смотрим содержимое файла
Здесь мы всё сделали через временный файл, громоздко, но по крайней мере безопасно. Веселый колпак тебе теперь точно не светит.
Можно извратиться и провернуть всё это дело на основе дескрипторов, но опять же этот способ не безопасен.
Можно правда хакнуть таким методом:
Это работает без временного файла на уровне Bash, потому что
Резюмируем: Не ссы использовать временные файлы, пусть твои bash скрипты будут безопасны и читаемы.
🛠 #bash #badpractices #bestpractices
—
✅ @bashdays / @linuxfactory / @blog
ㅤ
Создаём файл:
echo -e "foo\nbar\nfoo again" > bashdays.txt
Внутри получаем:
foo
bar
foo again
И применяем бэд-практику:
cat bashdays.txt | sed 's/foo/baz/g' > bashdays.txt
Эта команда читает файл
bashdays.txt и одновременно пишет в него.Что тут не так?
А всё! В лучшем случае получишь хуем по лбу и примеришь золотой пизды колпак. Эта команда испортит файл. Низя так делать! Всё проебёшь!
После этой команды файл
bashdays.txt обнулится. Хотя визуально команда выглядит абсолютно безопасной.А теперь делаем правильно!
sed 's/foo/baz/g' bashdays.txt > tmpfile && mv tmpfile bashdays.txt
Смотрим содержимое файла
bashdays.txt и видим ожидаемый результат:baz
bar
baz again
Здесь мы всё сделали через временный файл, громоздко, но по крайней мере безопасно. Веселый колпак тебе теперь точно не светит.
Можно извратиться и провернуть всё это дело на основе дескрипторов, но опять же этот способ не безопасен.
Можно правда хакнуть таким методом:
printf '%s\n' ',s/foo/baz/g' w q | ed -s bashdays.txt
Это работает без временного файла на уровне Bash, потому что
ed сделаем всё сам. Но опять же конструкция нихуя непонятная. Резюмируем: Не ссы использовать временные файлы, пусть твои bash скрипты будут безопасны и читаемы.
—
Please open Telegram to view this post
VIEW IN TELEGRAM
1 65
Нежных много, деловых мало. Ну не могу я из песни слов выбросить, получится сухо и не интересно.
ㅤ
Поэтому нарушать традиций не будем, продолжаем в том же ключе. А нежные пусть идут на... ну ты понял.
Рассмотрим распространённый случай:
Тут всё предельно ясно и понятно. Все в ажуре!
Но это вершина айсберга. Эта команда может отрабатывать не так, как ты ожидаешь. Потому что
Что подразумевается по «хитрыми штуками»
— Разделить содержимое на отдельные слова (если там есть пробелы).
— Подставить имена файлов с таким шаблоном, если он выглядит как
И тут у новичков возникает многочасовой проёб, когда переменная выводит неправильные значения.
Смотри:
Выглядит опять всё красиво. А по факту получаешь:
Да блядь! А я просто хотел вывести строкой
Первое
Поэтому, если ты хочешь наверняка вывести переменную как есть, лучше используй `printf`
Для маленьких:
Представь, что ты говоришь падшей женщине: «покажи что у тебя в трусах», она снимает трусы, а там — большой сочный хуй.
А чтобы в трусах был ожидаемый результат, нужно изначально это учесть в моменте знакомства (до просьбы) и расставить все кавычки.
Хотя у каждого свой ожидаемый результат… возможно кавычки вовсе и не потребуются.
Такие дела. Изучай!
🛠 #bash #badpractices #bestpractices
—
✅ @bashdays / @linuxfactory / @blog
ㅤ
Поэтому нарушать традиций не будем, продолжаем в том же ключе. А нежные пусть идут на... ну ты понял.
Рассмотрим распространённый случай:
echo $foo
Тут всё предельно ясно и понятно. Все в ажуре!
Но это вершина айсберга. Эта команда может отрабатывать не так, как ты ожидаешь. Потому что
foo это переменная. И если ты её не возьмешь в кавычки, то Bash может сделать с её содержимым всякие хитрые штуки.Что подразумевается по «хитрыми штуками»
— Разделить содержимое на отдельные слова (если там есть пробелы).
— Подставить имена файлов с таким шаблоном, если он выглядит как
*.zip (это называется глоббинг).И тут у новичков возникает многочасовой проёб, когда переменная выводит неправильные значения.
Смотри:
msg="Пожалуйста, введите имя файла в формате *.zip"
echo $msg
Выглядит опять всё красиво. А по факту получаешь:
Пожалуйста, введите имя файла в формате awscliv2.zip
Да блядь! А я просто хотел вывести строкой
*.zip а не получить список файлов в текущей папке.var="*.zip"
echo "$var"
echo $var
Первое
echo напечатает *.zip, а второе выведет список всех файлов, которые заканчиваются на .zip.Поэтому, если ты хочешь наверняка вывести переменную как есть, лучше используй `printf`
printf "%s\n" "$foo"
Для маленьких:
Представь, что ты говоришь падшей женщине: «покажи что у тебя в трусах», она снимает трусы, а там — большой сочный хуй.
А чтобы в трусах был ожидаемый результат, нужно изначально это учесть в моменте знакомства (до просьбы) и расставить все кавычки.
Хотя у каждого свой ожидаемый результат… возможно кавычки вовсе и не потребуются.
Такие дела. Изучай!
—
Please open Telegram to view this post
VIEW IN TELEGRAM
1 62
Живу в лесу, поклоняюсь колесу…
ㅤ
А чё эта хуйня не работает? Яж всё правильно сделал!
С виду всё верно. Но если внимательно прочитать команду и подумать, происходит такое:
Но у
А
Поэтому правильно так:
Теперь логика не хромает:
Вроде мелочь, а на эти грабли постоянно наступают и бегут — аа, у меня принтер не печатает!!! Что я делаю не так???
🛠 #bash #badpractices #bestpractices
—
✅ @bashdays / @linuxfactory / @blog
ㅤ
А чё эта хуйня не работает? Яж всё правильно сделал!
su -c 'ls -la'
С виду всё верно. Но если внимательно прочитать команду и подумать, происходит такое:
Хочу стать root и выполнить команду ls -la.
Но у
su другое мнение:Хочу стать пользователем с именем -c
А
-c — это не имя пользователя, а опция. Поэтому правильно так:
su root -c 'ls -la'
Теперь логика не хромает:
Перейти к пользователю root и выполнить команду ls -la.
Вроде мелочь, а на эти грабли постоянно наступают и бегут — аа, у меня принтер не печатает!!! Что я делаю не так???
А чем отличается su от sudo я писал тут, почитай на досуге и обнови нейронные связи.
—
Please open Telegram to view this post
VIEW IN TELEGRAM