Комментарии 108
Удивительно что нет http://tldp.org/LDP/abs/html/ в полезные ссылках
Синтаксис конечно вырвиглазный :) Даже на таких простых примерах…
Но за статью спасибо, пишите еще: периодически приходится с такими скриптами сталкиваться, и обычно натыкаешься на что-то такое, от чего мозг взрывается.
Надо бы эти моменты записывать, но не всегда получается. В общем, наконец-то появится возможность формализировать претензии к такому синтаксису.

Боюсь нарваться на минусы. Но синтаксис почти всегда дело привычки и вкусовщина. К примеру, да у bash синтаксис вырвиглазный, но шелл всегда под рукой и логично его для мелких автоматизаций использовать и, со временем, к нему привык и беглый взгляд на скрипты сейчас не вызывает отторжения. С другой стороны, по мне, так в том же Rust и Go синтаксис тоже не менее вырвиглазный, но пока потребностей их использовать не возникало и при взгляде на исходники возникает ощущение отторжения, что не умаляет их прочих достоинств.


А вот коллеге — нравится синтаксис Rust. А баш вызывает реакцию, похожую на вашу :)

bash устарел,

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

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


Да, в баше много чего нет. Мне, например, для удобства пришлось самому реализовать передачу внутрь функций и обратно из функций массивов. Точнее, закостылить (порядка 30 строк на всё), но это точно лучше, чем тянуть десятки и то и сотни мегабайт для подобного готового в питоне или чем-то еще более монструозном.

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

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

Так что я бы не рискнул сказать, что баш устарел. Может, он и не секси по нынешним временам, но по-прежнему полезен.

Что написано на баше можно запустить на любой никсовой машине без бубна.

Я вам приведу простой пример, чтобы было понятнее почему вам минусов накидали.
Пишете скрипт на bash из под Centos 7.x, кидаете на Ubuntu и оказывается, что там bash линкуется на dash, и ключевого слова function для декларации функции в «даше» нету.
Потом кидаете этот же скрипт на солярис и выясняете, что версия там доступного баша не 4.х, а 3.х и что новые вкусности вроде associative array, которые вы с такой радостью использовали, не будут работать.
Потом кидаете этот же скритп на HPUX и оказывается что там баша из коробки нет вообще, а только sh и понятное дело полскрипта просто не срабатывает.
А дальше либо начинаются танцы с бубном с приведением баша до нужной версии на всех системах (а это не всегда возможно), либо приходится скрипт переписывать с учётом доступных вещей в версии 2.x — для полной обратной совместимости с sh, чтобы-таки работало везде (и то я побоюсь дать 100% гарантию).
Немного утрированно, но вполне себе реальная рабочая ситуация с которой я тоже сталкивался.

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

Добрый день.


Спасибо за ваш комментарий. Да, такая ситуация действительно возможна.
За время работы с удаленным сервером и на Ubuntu не было таких проблем. Даже больше, все скрипты, что приведены в статье работают в ConEmu и на Windows 10.


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

НЛО прилетело и опубликовало эту надпись здесь
На dash линкуется не bash, а /bin/sh.

Чтобы не быть голословным я сейчас специально скачал 16.04.1 посмотреть. Тут вы правы. Либо я подзабыл, либо это поведение изменили (на даш я натыкался лет 5 назад)
А если в скрипте используются специфические bash-фичи, то по крайней мере странно начинать его с #!/bin/sh

Из собствсенного опыта — многие «Шапочники», к сожалению, этим грешат, и вот почему:
user@server:[~]: cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.1 (Maipo)
user@server:[~]: stat -c %N $(which sh)
‘/usr/bin/sh’ -> ‘bash’

user@server:[~]: cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.5 (Santiago)
user@server:[~]: stat -c %N $(which sh)
‘/usr/bin/sh’ -> ‘bash’
НЛО прилетело и опубликовало эту надпись здесь

На самом деле это недоработка Bash. Нужно напрячься и поискать пруфы, но вроде существует соглашение, если оболочка запускается симлинком с именем sh, то начинать в работать в режиме совместимости с классическим Shell. Тут как раз вопрос переносимости.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Кроме того, целью режима совместимости является запуск как можно бо́льшего числа POSIX‐совместимых скриптов, а не полная эмуляция POSIX shell. В идеале — все скрипты для POSIX shell запускаются и работают как в POSIX shell, а про несовместимые ничего не говорится — вполне могут и работать.


В zsh точно так же.

ConEmu, это всё-таки эмулятор терминала, а не шелл, так что скрипты работают не в нём, а в шелле конкретной версии, который в ConEmu запускается (а там у вас либо Bash 3/4.x в поставке Cygwin, либо тот же Ubuntu-Bash 4.x в поставке с WSL).
Чтобы понимать разницу между терминалом, эмулятором терминала, CLI и шеллом, и как оно всё взаимосвязано когда вы запускаете тот же ConEmu, советую покурить хотябы английскую википедию, там неплохо написано.

Полностью согласен с вами.


Чтобы понимать разницу между терминалом, эмулятором терминала, CLI и шеллом, и как оно всё взаимосвязано когда вы запускаете тот же ConEmu, советую покурить хотябы английскую википедию, там неплохо написано.

Курил ) Норм зашло.


Не хотел ввести в заблуждение.

кидаете на Ubuntu и оказывается, что там bash линкуется на dash

стоп. Bash никуда не линкуется. А вот sh линкуется на dash по умолчанию и поэтому многие скрипты, которые пишут:


#!/bin/sh

а используют башизмы начинают обламываться. Но мне одному кажется, что это сродни использования, например, memfd и ругаться, что переносимость у C хреновая, когда на целевой OS (не Linux или Linux < 3.17) оно не заработало или начало валиться?


UPD: уже увидел обсуждение этого нюанса.

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

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

А вот что то посерьезнее — установщики, сложные бэкап скрипты, все что > 25 строк, я бы предложил Питон, D, Lua, или JScript (windows)
Все вами перечисленное в принципе уберется в 25 строк на баше (даже меньше, если уметь пользоваться rsync и манипуляцией файлов). Если только нет множества вариантов пользовательских параметров для своего скрипта.
НЛО прилетело и опубликовало эту надпись здесь
Ваш случай просто подтверждает факт, что для каждой задачи должен быть свой инструмент. Не пишите на bash большие вещи, он для другого сделан.
это проблема постановки задачи и выбора неверного инструмента для ее решения в чистом виде, а не bash'а

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

Хотелось бы добавить, что совсем не обязательно выставлять скрипту атрибут исполняемого файла. Скрипт можно запустить и командой: bash <имя файла скрипта>.

Добрый день.


Спасибо за ваш комментарий. Добавил в статью упоминание об этом.

Нет, нельзя. Ни в коем случае не запускайте так скрипты: bash script.sh запускается в отдельном процессе. Если скрипт для своих нужд перейдёт в другой каталог, добавит/удалит путей в $PATH, изменит $IFS или что‐то подобное и, разумеется, не восстановит состояние (разумеется — это же скрипт — оболочка, в которой он будет запущен, будет убита по окончанию скрипта), то с последствиями всего этого при использовании команды . вам придётся иметь дело в своей более не уютной интерактивной сессии, т.к. скрипт будет запущен внутри этого процесса.

И ещё одно соображение: скрипт запускается с настройками, предназначенными для исполнения скриптов. А при использовании . из интерактивной сессии будут использоваться интерактивные настройки, что может изменить поведение. В т.ч. активны aliasы (обычно не особо проблемно, но если что‐то не так, то вы получите ошибку на ровном месте, а aliasов у меня много, в т.ч. на распространённые вещи вроде alias cp='cp -iR').

Для начала нам нужно знать где находится bash. Эта информация нам понадобиться при написании самих скриптов. Чтобы узнать где находиться bash, выполните следующую команду:
which bash # где находится bash


Любой скрипт на bash должен начинаться со строки:
#!/bin/bash

Вопрос: ну и зачем вызывался which?


Обработка аргументов внутри скрипта:

Куда делась $@?


Первые три варианта схожи и каждая следующая конструкция дополняет предыдущую. Рассмотрим самый простой вариант:
if [[ condition ]]
…

Такое описание if мне категорически не нравится, оно предполагает, что [[ … ]] является частью синтаксиса if, хотя это совершенно не так. После if идёт команда — любая. Упрощения неуместны, вещи вроде if grep 'foo' ../bar встречаются слишком часто, чтобы это игнорировать и отложить «на потом». Аналогично с while, здесь даже хуже: [в /usr/share/bash-completion] echo $[1.0 * $(ag 'if \[\['|wc -l)/$(ag 'if \w'|wc -l)] даёт 6.3 (ваш вариант используется в шесть с лишним раз чаще), тогда как echo $[1.0 * $(ag 'while \[\['|wc -l)/$(ag 'while \w'|wc -l)] даёт 0.74 ([[ используется в 1,4 раза реже).

Добрый день, Николай.


Спасибо за ваш комментарий.


Вопрос: ну и зачем вызывался which?

Чтобы узнать где находится сам bash


Куда делась $@?

Обновил


Такое описание if мне категорически не нравится, оно предполагает...

Да с if, while немного незадача вышла. Хотя на разных ресурсах предлагаю по-разному. И тот же Google рекоммендует if в разных вариациях

Чтобы узнать где находится сам bash

А зачем это узнавать, если в первой строчке всё равно #!/bin/bash? И оно должно так и оставаться, потому что это стандарт де‐факто. Даже если в вашем дистрибутиве /bin — это ссылка на /usr/bin и она отсутствует в $PATH по‐умолчанию (и, соответственно, which bash выдаст не то).


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

Тут ниже говорят, что новым стандартом де‐факто должно быть #!/usr/bin/env bash. Но и с ним which не нужен.

На эту тему очень много неоднозначностей.


К примеру, это просто стечение обстоятельство, что на многих системах env лежит в /usr/bin/. Встречаются и такие, на которых /bin/env (мне какая-то сборка специализированная попадалась). Расположение этой команды не регламентирутся никакими стандартами, типа FHS.


Т.е. собственно на такой паттерн можно рассчитывать точно так же, как на /bin/bash.


Затем, это повод для вмешательств такого рода:


cd /tmp
touch bash
chmod +x bash
vim bash
export PATH=/tmp:$PATH

после чего, выполняя любой скрипт с #!/usr/bin/env bash, он будет передаваться на управление не bash, а вашему скрипту/программе. С одной стороны — гибкость. С другой — уязвимость. Где-то тут на Хабре недавно эксплуатация этой особенности демонстрировалась.

Не получится с bash, подменят так mv. И вообще, если есть доступ к переменным окружения то можно и такое устроить:


env BASH_FUNC_echo%%='() { builtin echo vulnerable $@; }' bash -c 'echo abc'

Это я к тому, что никаких новых уязвимостей #!/usr/bin/env не создаст.

О, про такой трюк не знал. Но было бы неплохо иметь гарантию нахождения env в каком-то определённом месте. И лучше бы это было просто /bin/env. А то /usr/bin/env ни разу не регламентировано, хотя, де-факто, стандарт и дистростроители вряд ли это будут ломать.

НЛО прилетело и опубликовало эту надпись здесь

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

Куда делась $@?
Обновил

Как раз вот


"$*" # все аргументы в виде одной строки (слова)

можно было бы и опустить: быстрое исследование ((cd /usr/share/bash-completion ; ag '\$(?:\{[#!]?)?\*')) показывает, что во всём каталоге /usr/share/bash-completion $* встречается ровно 1 (один!) раз — в строке 258 local items="${*}" файла helpers/gentoo-common.sh. Ещё один раз в комментарии и два раза в виде \$* (т.е., по сути, не переменной $*). Заметьте: подсветка синтаксиса хабра даже не подсветила эту бесполезную вещь как переменную:


всё подсвечено, а $* — нет

Вопрос: ну и зачем вызывался which?


Версия: Чтобы узнать где находиться bash и поместить его (если он не там) в /bin/bash?

Возможно. ;-)

И ещё: var1=$1, [[ -f $1 ]], rm $1 и множество подобных — можете мне точно сказать, в каких случаях не нужно использовать "" вокруг переменной и почему? Лучше сразу показывать новичкам безопасный код и писать кавычки просто везде, поскольку это проще, чем помнить, где их можно и не писать и исправлять опасные привычки.

Вот да.
Я надеялся что этот момент будет освещён.
Я 99% времени трачу потом на попытку хоть как-то расставить кавычки, что бы оно хоть как-то работало.
По поводу кавычек вы правы. Хотя и спорный вопрос. Тут можно растянуть обсуждение надолго. Если кратко, то желательно использовать двойные кавычки ("") при обращении к переменным. Это предотвратит интерпретацию специальных символов, которые могут содержаться в именах переменных, за исключением $, ` (обратная кавычка) и \ (escape — обратный слэш).

Но опять же, в данном, конкретном случае — это лишнее

При чём тут имена? Двойные кавычки нужны, чтобы файл с именем home с именем malicious -rf (с пробелом в конце) не привёл к удалению содержимого /home, когда вы будете писать rm $1. Кавычки нужны, чтобы значения переменных оставались одним куском, имена тут ни при чём. И в данном конкретном случае это совсем не лишнее: во‐первых, писать кавычки нужно всегда, просто чтобы написать их и когда нужно. Во‐вторых, вы пишете rm $1, причём $1 получен от пользователя. А если я хочу подобным скриптом удалить что‐то в ~/.wine/drive_c/Program Files?

НЛО прилетело и опубликовало эту надпись здесь
Ну почему bash?


В нём есть ряд забавных приколов, которые весьма удобны при программировании — и чего нет в sh/dash.
Да, и автор зря, пмсм — не указал вот эту замечательную книжку.
Хоть она и «advanced», но написано неплохо, и кривая освоения в ней достаточно плавная.
я всем начинающим консолеводам рекомендую fish, понятно что bash и shell — это основные игроки, но fish намного проще и интуитивней, особенно для начинающих, ну и поставить фиш не так сложно.

fish слишком ограничен. Если твоё понимание того, как должна вести себя консоль совпадает с авторскими и тебя устраивают урезанные возможности по написанию однострочников — то всё в порядке. Но с моей точки зрения это не «начинающий консолевод», а «я иногда немного пользуюсь консолью и не собираюсь пользоваться ею интенсивнее».


И я не знаю, с чего вы решили, что «поставить фиш не так сложно» — fish, вообще‐то, единственная оболочка, которой требуются runtime файлы (то, что в /usr/share/fish) для базовых возможностей (того же math). Bash такое нужно только для автодополнения. Zsh — автодополнение и некоторые дополнительные возможности, но она вполне обходится и без них. Различным POSIX shell ничего вообще не нужно: продвинутого возможностей нет, даже более‐менее интелектуального автодополнения. Ну а там, где можно ставить fish/bash/zsh обычно установка любой из альтернатив — дело одного запроса пакетному менеджеру. Несмотря на требования наличия runtime файлов никаких трудностей ни с одной оболочкой я не испытывал, что ставя пакетным менеджером, что используя make install для установки тестируемой версии в нестандартный (не /usr или /usr/local, а что‐то вроде ~/.local-fish) каталог.


И что такое «shell»? Вообще‐то это слово обозначает просто «оболочка» — класс программ, в который входят и zsh, и fish, и bash, и busybox, и dash, и много чего ещё.

1. чем наличие рантайма плохо? Вы же не собираетесь деплоить фиш с одной машины на другую.
2. фиш легче освоить так как там более понятный и привычный синтакисис, как минимум для программистов, я честно пользоватлся bash лет 12, и до сих пор не могу привыкнуть к его синтаксису, хотя мой юз-кейс ограничен гитом, cat и скриптами автоматизации максиму строк на 200-300.
3. Я не считаю что более сложные вещи, нежели то что можно уместить в 20-40 команд нужно писать на скрипте интерпретатора, поддерживать такое хозяйство тяжело, мне лично проще взять ruby или golang и накидать быстренько более сложную логику в виде пиложения: намного богаче набор библиотек, легко поддерживать и тд. Хотя сложные вещи пытался писать: системы сборки, тулчейны и деплой скрипты. Всё это геморойно, как по мне.
4. shell, я имею вввиду «sh» — Bourne shell.
  1. Тем, что чем больше файлов, тем больше потенциальных проблем. С моей точки зрения fish не отличается от zsh по сложности установки, но если бы меня спросили, какая оболочка должна была бы быть более сложной, то я бы назвал fish.
  2. Я не отрицаю, что он простой. Но ограниченный: Cannot save multi-line output in a variable — запросу уже четыре полных года. Я не могу нормально работать с таким языком, даже несмотря на то, что он понятнее zsh. А на zsh можно отлично писать write-only однострочники там, где в других оболочках пришлось бы писать скрипты.
  3. Я тоже почти никогда не пишу какие‐то сложные скрипты для оболочки. А вот разные сложные однострочники (часто что‐то массово скачивающие из интернета) бывает — обычно что‐то, подо что perl теоретически подходит лучше, только zsh я знаю лучше. Иногда пишу автоматические тесты, но при большой сложности они переписываются на основном языке проекта.


    Проблема в том, что для fish я писал в основном только powerline-setup.fish, и fish бесил меня даже в таком простом файле:


    1. test, env, math: создаётся впечатление, что у fish просто нет своих возможностей: лишние процессы на каждый чих (math использует внешние программы).
    2. Конструкция вида (dirname (status -f))/../../../scripts/powerline-config меня напрягает: я отлично понимаю, что теоретически dirname может вернуть имя каталога с новой строкой внутри.
    3. Отлаживать совершенно невозможно: нет set -x. fish -d выдаёт слишком много либо слишком мало информации, уровень выдачи информации не изменяется во время работы, на некоторые вопросы ответить по выдаче сложно или нельзя (пытался найти в логе пользователя, кто, где и почему изменяет fish_prompt — не нашёл ничего внятного). И да, если с установкой кучи runtime файлов проблем нет, то вот с тем, что они спамят вывод fish -d проблемы есть.

  4. А она где‐то ещё используется? В linux дистрибутивах сейчас в качестве /bin/sh обычно либо bash, либо dash. Иногда busybox, но это больше для систем с ограниченными ресурсами. Теоретически ещё могут быть zsh, а также другие клоны bourne shell вроде posh. В целом это дело обычно называют «POSIX‐совместимыми оболочками» и предназначается исключительно для скриптов. Busybox ещё предполагает интерактивное исполнение, но вот у posh и dash оно скорее для галочки и нет даже автодополнения, поэтому игроками они считаться не могут.


    В некоторых дистрибутивах (я использовал из них grml и babun (сборка cygwin)) используется предустановленный zsh. Ещё как‐то ставил на виртуалку FreeBSD для тестов, там tcsh в качестве интерактивной оболочки по‐умолчанию (скрипты на этом писать на порядок сложнее, чем на любом другом языке из семейства *sh, что я видел).


Как-то узнал про fish и поставил его, протащился. Радости хватило на пару дней. Потом стало неуютно. Узнал про zsh, поставил, протащился, нахлобучил настроек. Через пару дней начались тормоза. Плюнул, запустил man bash, почитал, настроил в .bashrc почти все нужные мне фишки от zsh/fish и успокоился.

С тех пор всем советую, прежде чем к любому софту искать книги, курсы и прочий хлам, сначала read the fucking manual.

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

да уж, про условия в bash написано вообще ужасно. нет if grep, if [, только if [[.


остальное на совести автора.


Ну и понятно, всегда лучше поставить oh-my-zsh и не париться.

Oh-my-zsh имеет плохую репутацию у разработчиков самой zsh. Подробно можно расспросить на канале в freenode, но насколько я понял претензии такие: во‐первых, OMZ выполняет работу, которую уже выполняет zsh. Во‐вторых, когда что‐то идёт не так и пользователь приходит на канал, чтобы спросить совета, отлаживать OMZ на порядок сложнее.

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

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

Добрый день, Акжан.


Спасибо за ваш комментарий.


да уж, про условия в bash написано вообще ужасно. нет if grep, if [, только if [[.

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


Привел пример синтаксиса, который использую ежедневно. Не испытываю проблем с написанием if [[ ... ]]. Хотя тут во всех примерах if [ ... ]. А тут в большинстве рекоммендаций используется вариант if [[ ... ]]


Ну и понятно, всегда лучше поставить oh-my-zsh и не париться.

Сарказм детектед или нет?

Скорее из жизни. Я и вправду bash использую только в железобетонных скриптах, где есть уверенность только в наличии bash.

НЛО прилетело и опубликовало эту надпись здесь
Надо знать bash…
… чтобы генерировать скрипты service application command :)

Не более.
НЛО прилетело и опубликовало эту надпись здесь
Это была шутка.

Не более.

P.S. В баше уже более 12 лет почти каждый день работаю.
P.P.S. Даже свой терминал с картинками делал на python.

Python очень многословен на фоне bash. Не надо забывать, что сам по себе шелл довольно плох, но его в здравом уме и не используют для написания серьёзных программ. Он нужен как клей в unix среде и с этой ролью он справляется лучше чем python, поскольку имеет специально заточенные под это примитивы, типа перенапрвления потоков, опроса выходных параметров и управления фоновыми задачами. На python все это разумеется есть, но не на уровне примитивов.

Вообще, спорно. Языки разные с разными целями и подходом. Есть вещи, которые на bash делает в одну команду, а python — в несколько и нетривиальных.
Примеры:
1) Сохранить вывод программы в файл (>, grep, cut и т.д. по необходимости против ProcessOpener и работы с потоками вручную)
2) Скачать файл на диск (wget против urllib2 подключением ProxyHandler)

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

Дооо…
$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
$ wget
-bash: wget: command not found
$

Ооопс. С коих пор wget стал bash'ем-то? =)

Вот потом и разгребай такие скрипты…
Давайте расскажите мне про совместимость Python 2 и Python 3 в случае переноса с системы на систему.
Переход на светлую сторону. Bash
Покайтесь, ибо грядёт Ansible с python'ом и j2 под капотом

Добрый день.


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

Просто забеспокоился, что за чёрную магию вы использовали, что даже bash после неё — «светлая сторона». А Ansible — имхо, то чем стоит сегодня заменять bash скрипты

Вы собираетесь использовать Ansible в роли быстрого "однострочника" для запуска перла/грепа/авка/седа?
Извините.

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

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

Ни о какой "Черной магии" не идет речь. "Светлая сторона" — это посыл всей серии статей про консоль.


А Ansible — имхо, то чем стоит сегодня заменять bash скрипты

Можно пруффы? А то только и слышу, что "bash ужастен...", "Он не годится..."
Чем лучше Ansible?

Более высокоуровневое API автоматизации, красивые архитектурные решения, описать которые в одном посте не возьмусь, но вот для статьи он точно интереснее чем bash, про которые всё написано даже на русском не по одному разу.
Ansible is a radically simple IT automation system. It handles configuration-management, application deployment, cloud provisioning, ad-hoc task-execution, and multinode orchestration — including trivializing things like zero downtime rolling updates with load balancers.

есть подозрение что вы путаете лопату и перфоратор, лопатой тоже стену можно пробить, но зачем?
Любой скрипт на bash должен начинаться со строки:
#!/bin/bash


Вообще говоря, лучше так не писать, за исключением /bin/sh, потому что bash совершенно не обязан лежать в /bin. В той же FreeBSD он ставится из портов совсем не в /bin (возможно, что-то изменилось с моего последнего использования этой системы). А в скриптовых языках вроде python абсолютные пути (помимо того, что бинарь может лежать совершенно не там, где ожидает автор скрипта) еще и ломают virtualenv.

Более универсальна форма записи:
#!/usr/bin/env bash

Лучше вообще не писать на баш с расчетом на кросиспользование с Freebsd, поскольку там будет куча проблем c совместимостию gnu и bsd утилит, а расчитывать на установленные порты это рисковано. Поэтому только голый sh, и максимально древние спеки sed, awk, grep.


Ну и во-вторых, ну ребят, ну все уже. Мне конечно ещё приходится иногда писать с учетом Unix/Aix/Solaris, но для большинства вопросы совместимости уже не стоят. Linux захватил Unix сервера прочно.

Добрый день.


Спасибо за ваш комментарий.


Более универсальна форма записи:
#!/usr/bin/env bash

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


#!/bin/bash

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

НЛО прилетело и опубликовало эту надпись здесь
Мы же серьезные люди и не будем ничего доказывать частными случаями?

Тут даже не буду спорить. Не стоит переходить на такой уровень )


А вот по поводу ссылки на вики, это вы лихо

Любой скрипт на bash должен начинаться со строки:
#!/bin/bash

Вроде как давно уже рекомендуется эта запись:


#!/usr/bin/env bash

Добрый день, Виктор.


Спасибо за ваш комментарий.


Выше в ответе на комментарий FFiX описал сиутацию, почем так. Повторюсь. С данной формой записи:


#!/bin/bash

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


#!/usr/bin/env bash

Чтобы к следующей статье я был более подготовлен и не использовал в своей работе устаревшие подходы и решения


Те скрипты, что приведены в статье работают на: Ubuntu, ConEmu, Windows 10, удаленный сервер.

Спасибо за ссылку. Добавил в список полезных. Позже обновлю примеры

Должен заметить что я тоже постоянно пишу #!/usr/bin/env что_то_там, и не только для баша. Я не вспомню где я это в своё время нарыл, но связано это с тем что баш (да и не только) не обязательно валяется в /bin, см. взять хотябы HP-UX из моего поста выше.
Вот простой пример:
[user@server ~]$ uname -a
HP-UX server_name B.11.31 U ia64 redacted_machine_id unlimited-user license
[user@server ~]$ which bash
/usr/bin/bash

Сталкивался со случаями, когда в системе была одна версия баша/пайтона/перла, а для конкретного пользователя/задачи ставилась другая куда-нибуть в /opt, например просто потому что нет возможности поставить нужные библиотеки. Через environment variable можно тем самым для конкретного пользователя задать где валяется бинарка и иметь переносимый между системами (например dev и prod) код.

Г-н Borz уже успел скинуть ссылку на «стэк» постом выше.

Добрый день, Владислав.


Спасибо за ваш комментарий. В данном конкретном примере это не критично. Что вас не устроило ?

Вообще‐то это проблема гигиены кода, отсутствие кавычек здесь не создаёт опасной ситуации, насколько я знаю. Я лично всё равно предпочту написать кавычки — это проще, чем закопаться в man bash, чтобы подтвердить экспериментально проверенное отсутствие проблем. Но вот писать в кавычках ещё и фигурные скобки — зачем? Там текста дальше нет, будет текст — поправите, подсветка синтаксиса в редакторе не даст пропустить ошибку.

Отсутствие кавычек и {} в примере под названием «одной переменной присваиваем значение другой» создаёт очень опасную ситуацию в виде тонн говнокода на баше и всяческих сказок вида «этого на баше нельзя, это на баше писать плохо» и прочей чуши.

С кавычками согласен, с фигурными скобками — нет. Но упомянуть «если нужно, то пишите» не лишне.

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