Pull to refresh

Comments 114

Читайте Advanced Bash-scripting guide и Linux phrasebook Скотта Граннемана :)
Advanced Bash-scripting guide — действительно отличная книга :), а Linux phrasebook как-то хотел купить себе, но полистал и подумал, что быстрее будет пользовать --help и man )
Это я так, по поводу упоминания сего руководства. Вдруг кому пригодится.
А вы проверять свои примеры пробовали? Первый пример выдаст вовсе не то, что вы там понаписали, а вот это:
$ ./test.sh qwerty
/bin/bash: #указываем где у нас хранится bash-интерпретатор: No such file or directory
А если первую строку исправить, то вот это:
$ ./test.sh qwerty
Вы запустили скрипт с именем ./test.sh и параметром qwerty\n
Вы запустили скрипт с именем $script_name и параметром $parametr1

В пером примере ошибка появляется потому, что строчка с коментарием переходит на следующую строку. Коментарии я уже пишу после того как оттестю программу
А в «qwerty\n» — мой косяк ) \n должен быть за скобкой ", приношу извинения
1. Комментарии никуда не переходят. Просто Shebang их не поддерживает.
2. \n там вообще не нужен.
поправил, спасибо
в любом случае спасибо, полезная заметка.
2)
/usr/bin/vi # если $doing содержит 2, то запустить nano
;;
3)
/usr/bin/emacs # если $doing содержит 3, то запустить nano


в комментах ошибка.
Спасибо. Давно хотел познакомиться с синтаксисом BASH'a. :)
Буду читать вашу серию постов об этом языке.
2 года использую баш в повседневных задачах, но с трудом понял то, что уже знаю, как это будут понимать новички — не понимаю.
Я уже сейчас конец предложения понять не могу :(
А что конкретно не понятно? Примеры? Описания? Я был бы рад критике, но поконкретней пожалста и попонятней))
Может я немного не понял ваши намерения, но создается такое впечатление, как будто вы хотите рассмотреть баш как язык программирования, в отрыве от реалий и основных задач, для которых он используется. Сразу начали с передачи параметров скриптам, выместили кучу редко используемых операторов, рассмотрели все возможные операторы условий для циклов… Если ваша цель — по быстрому рассказать кодеру об еще одном языке программирования, то подход в принципе верен. Если же вы хотели познакомить с удобным инструментом решения повседневных задач новичка в мире *nix, то вы его только отпугнете.
Если вы хотели добиться второго, то лучше начать с примеров вроде cat some.log | grep error или echo >> ass=true ~/.mplayer/mplayer.conf
Свою цель я описал в первом абзаце.
неужели вы с этого учились писать скрипты на коленке? :)
O'Relly Bash Cookbook — шикарная штука для начинающего. А то пока с експаншэнами всеми разберешься, писать расхочется уже: порог освоения высокий очень. А так, в одной руке www.gnu.org/software/bash/manual/bashref.html, а в другой кукбук.

Эх. Вырасту, вот, для GUI аналог bash сочиню. Не система диктует что делать, а наоборот. Процедурные… проэктивные рабочие среды… ч-т… Организация рабочего пространства.
tcl/tk же.
tcl — командный язык типа bash, но гораздо более расширенный. tk — простейшая библиотека для написания gui.
надо посмотреть.
Вообще, я имею ввиду, эту фишку баша, что в гамках командного интерфейса ты посредством пайпов и тп и многочисленных утилит можешь себе дворцы в терминале строить. То есть, для GUI аналогом были бы механизмы перенаправления потоков даных, соответствующие интерфейсы для утилит и инструменты для сборки комплексов подстать особенностям GUI как такового.
То есть, виджет, выдающий сколько в гугл-ридере новостей про bash я сейчс за месяц =) можт и могу наваять, а адекватных GUI средств для подобного рода выкрутасов пока нет. Даже концепций.

Это я все к тому, что современный юниксовый GUI, решив идти со всеми, потихонюку перенимает неповоротливость и отсутствие хоть сколько нибудь адекватной гибкости, присущие другим известным операционным системам.
Услышав про гамак, сразу как-то вспомнилась фраза про секс в гамаке, но это так к слову. А про gui, я думаю к нему не надо примешевать логику. Лучше, как в паттерне mvc, Gui — будет view и controller, то есть в его задаче будет только связь с консольными приложениями или ядром программы.
П.С. На тикле в принципе за пару часов могу такую прогу написать, у гугл ридера же апи нормальный, правда скорее всего придется скачивать всю ленту и здесь сортировать, но я апи только бегло посмотрел)
На самом деле оператор условия имеет вид:
if command
then
list
elif
list
else
list
end if

[[ — это специальная команда, которая возвращает результат указанного внутри выражения

то есть условие «if grep -q root /etc/passwd» тоже нормально сработает
Не совсем. Квадратная скобочка требует парной закрывающей, test — не требует…
Но, так или иначе, [ — это симлинк на test. Просто при вызове [ эта команда требует обязательный аргумент ] :)
Однако, это уже всё тонкости. Просто некоторые считают [ ] конструкцией оболочки, в то время как это обычный запускаемый бинарник.
ubique@ubique ~ $ ls -alho /usr/bin/[
-rwxr-xr-x 1 root 38K Jun 17 2008 /usr/bin/[
ubique@ubique ~ $ ls -ahlo /usr/bin/test
-rwxr-xr-x 1 root 26K Jun 17 2008 /usr/bin/test
ubique@ubique ~ $ uname -o
GNU/Linux
Правда ваша :) Перед тем как написать не проверил на других системах. В альте у меня симлинк стоит, в редхате два разных бинарника, а в слаке вообще и [, и test, лежащие в /usr/bin являются симлинками на соответствующие бинарники в /bin
Но, так или иначе, [ — это симлинк на test
А если вы используете busybox, то у вас вообще все утилиты будут symlink'ом на один файл. Теперь будете говорить что ls, cp и rm — это одно и то же?
Просто некоторые считают [ ] конструкцией оболочки, в то время как это обычный запускаемый бинарник.
Нет, это не «обычный запускаемый бинарник». Сравните:
$ touch test.txt
$ if [ -N "test.txt" ]; then echo "test.txt is modified"; else echo "test.txt is not modified"; fi
test.txt is modified
$ if /usr/bin/[ -N "test.txt" ]; then echo "test.txt is modified"; else echo "test.txt is not modified"; fi
/usr/bin/[: extra argument `-N'
test.txt is not modified
Поведение встроенное команды и внешней отличается. Более того: внешняя команда живёт в /usr/bin и, соответственно, не может быть использована в rc-скриптах! В более старых shell'ах это был «обычный запускаемый бинарник», в bash — это конструкция оболочки. Совместимая на 99%, но, как вы говорите, «это всё уже тонкости»…
Повержен в пух и прах, признаю все свои ошибки. :)
Оказывается, всё давно изменилось…
я бы еще про chmod упомянул :) без
chmod +x script.sh
./script.sh работать не будет :) для некоторых это неочевидно
В первой версии статьи это было, но ввиду неожиданного отключения электричества и разобранного УПСа на столе, она не сохранилась(
Простите за небольшой оффтопик, но есть такой замечательный шелл как fish — он чем то похож на питон и гораздо более юзерфрендли чем баш. Ну по крайней мере мне так показалось.
Новичкам его советую однозначно, остальным — по желанию =)
Существует множество разных шеллов различной степени дружелюбности и гиковости, однако bash — это стандарт, его синтаксис должен понимать каждый. А вот остальные, как раз, по желанию.
Стандарт для написания скриптов — sh.
Не поленился и проверил на разных системах командой
grep -sR ^#! /etc|perl -F: -ane 'chomp $F[1];$F[1]=~/^#! ?([^ ]+).*$/;$h{$1}++;END{while (($shell,$count)=each %h){print "$shell $count\n"}}'

Fedora 9:
/usr/bin/perl 1
/bin/sh 703
/usr/bin/pulseaudio 1
/bin/csh 1
/bin/bash 656

Ubuntu 8.10:
/usr/bin/perl 4
/bin/sh 520
/usr/bin/pulseaudio 1
/usr/bin/python 2
/bin/bash 27

Debian
/usr/bin/perl 1
/bin/sh 166
/usr/bin/install-menu 5
/bin/bash 9

Т.е. в некоторых случаях bash действительно используется как основное средство написания скриптов, но большая часть скриптов все-таки на sh.
Принято писать на sh, а не каких-то других скриптах, потому что sh предоставляет необходимый минимальный функционал. И то что будет нормально работать на sh, с очень большой вероятностью будет работать и на других интерпретаторах.
>1. Любой bash-скрипт должен начинаться со строки:
#!/bin/bash

Извините, но сие не есть правда. Шебанг нужно указывать только в случае, если текущий интерпретатор отличается от того, на языке которого написан скрипт. Т.е., если дефолтовым шеллом у вас csh — то без шебанга sh-скрипт не отработает; точно так же не отработает под любым шеллом perl-скрипт без указания #!/usr/bin/perl в начале его и запуске через ./script.pl
Лучше на это не полагаться. Мало ли какой shell использует человек…
автор наверное написал так, чтоб не пугать новичков =)
Да, действительно. Целью статьи, я поставил для себя описать минимум для работы и более-менее свободного(и удобного) написания скриптов. Кто захочет, тот сам найдет больше информации. Все равно в рамках 1ой ознакомительной статьи не описать всего.
А ещё можно писать, к примеру:
#!/usr/bin/env perl
Тоже будет работать =)
Однажды мой знакомый полдня убил, чтобы понять, почему в слаке не отрабатывает скрипт /etc/ppp/ip-up после поднятия pptp-подключения. При том, что если запускать скрыптик вручную, то команды предательски выполняются.
Оказалось, что он забыл поставить волшебный шебанг в начало файлика, и pppd не смог его запустить.

Всего один пример, но, блин их ведь куча может быть :)
Кстати, а /bin/sh не умеет что-то из того, что есть в статье?
О, то что надо, спасибо, я как раз сейчас «грызу» консоль =)
Хотелось бы чтобы вы не обошли стороной именно бэкапы. :)
Грубо говоря — есть сервер с Н пользователей — у каждого свои проекты. Вот хотелось одним скриптом собирать все подпапки с проектами и каждый класть в отдельный архив.
Т.е. нужно знать — как обходить директории и как выполнять программы. тар, например. :)
Если хотите ознокомиться с стандартными рецептами бекапов в nix — попробуйте почитать книгу «Unix backup and recovery»
Немного кривой код, но рабочий.
find * -maxdepth 1 -type d | xargs -I '{}' tar cvf '{}.tar' '{}'
Выбирает все подпапки из папки и каждую кладет в отдельный tar файл. Для настройки даты последнего изменения итп смотрите man find.
find. -maxdepth 1-mindepth 1 -type d -exec tar czf '{}.tgz' '{}' \;

find.unixpin.com
Большое спасибо вам. Всегда думал, что существует простой путь юзания имени файла в find -exec несколько раз.
Не обязательно любой shell скрипт должен начинать с #!(sha-bang). Например — подключение shell скриптов с помощью. — тот скрипт который мы подключаем не обязан иметь sha-bang в начале.
Почему пост исключительно направлен на тех, кто использует linux? bash практически де-факто стандарт для всех пользовательских shell'ов. Где-то встречал рекомендацию, чтобы оформлять sha-bang так # !/bin/sh. Именно пробел после #. Только не понял для чего это используется:)
Если планируется писать скрипты, которые должны работать на всех видах nix, то лучше писать исключительно на sh, не употребляя дополнительные возможности bash или какого-нибудь специфичного интепретатора.
Пробел после # может использоваться чтобы обмануть шибко умный парсер на каком-нибудь сайте. А в реальном файле его быть не должно. Ибо в fs/binfmt_script.c:
25         if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
26                 return -ENOEXEC;
Куда там пробел вставлять?

P.S. bprm->sh_bang — это хитрый хак для как-бы-вставления в начало IA32-файла строки #!/usr/bin/em86, больше он нигде не используется…
Пробел после восклицательного знака, а не после октокорпа. Вставлять этот пробел рекомендует «Autoconf Manual: 10. Portable Shell Programming» [1]. Однако «The '#!'-magic, details about the shebang mechanism on various Unix flavours» [2] опровергает необходимость этого. Также неверно утверждение khim («в реальном файле его быть не должно»), это видно даже по приведённому отрывку кода.

[1] www.gnu.org/software/autoconf/manual/autoconf-2.57/html_chapter/autoconf_10.html#SEC114
[2] www.in-ulm.de/~mascheck/various/shebang/#details

P.S. Вставить нормальные линки не позволила низкая карма :(
Давайте не приписывать мне слов, которых я не говорил. После #! пробел может быть нужен на старых системах, внутри #! — никогда.
Прошу прощения. Вы действительно правы по поводу того, что внутри «#!» пробела быть не должно. Позволю, однако, не согласиться с тем, что «после #! пробел может быть нужен на старых системах». Приведите пример хотя бы одной системы, требующей 32-битный magic «#! /», а не 16-битный «#!».
«это еще и превосходный скриптовый язык программирования.»
Да ладно вам, язык очень и очень хреновый, если можно него не юзать — нужно его не юзать. Единственный плюс (да, если это всё же sh) — кроссплатформенность.

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

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

Если вторую — да, куча всего уже написано на sh/bash, уметь разбираться в этом и дорабатывать тоже нужно. Но если есть возможность переписать на чём-то более читабельном — почему нет?
Вот так и знал, что Вы стороник python. Вы предлагаете ставить на каждый сервер python?
Синтаксис наооборот — наиболее простой, конечно если не стараться все запутать, впрочем это можно сделать на любом языке. Любые Вещи делаются приятнее? А сделайте мне, вот такой простой аналог на python `cat /etc/passwd | awk -F ':' '$1>1000{$print $3}' | sort -r`. Говорите приятнее? Про использование повторно — вообще не понял. Что Вы shell скрипты повторно использовать не можете? А короткие команды можно и в alias загнать. Если Вы имели ввиду использование библиотек, то кто Вам мешает подключать другие shell сценарии в свой? Только что не знание того, что это можно делать.

Shell — стандарт серверных скриптов и слава богу, python'y до этого еще далеко. Единственное причина, из-за которой можно уходить от shell — необходимость реализации более сложной логики в скриптах. Но никто не говорит, писать различные engine или биллинг на sh.
В вашем примере используется awk, с каких пор awk является частью sh? Да и молчу я вообще про него.
Я не сторонник Python, я сторонник понятного, читаемого кода, да и подцепить любую shell команду к нему не сложно.

«Синтаксис наооборот — наиболее простой» Короткий ≠ простой.
Почему, чёрт побери, условие в квадратных скобочках, где нормальные выражения?
Кто придумал ;; в case?
Почему всё так стремится быть брейнфаком?
Почему просто не взяли синтаксис Си, доработали его до того уровноя, на котором легко можно обрабатывать массивы в циклах (for (xxx in yyy) {})?

«Вы предлагаете ставить на каждый сервер python?» Слова-обобщения мне всегда не нравились. Всему своё место.
Потому что sh без сторонних программ — не дает толком ничего. shell является прослойкой между терминалом пользователя и сторонними програмами, которые являются частью base-системы и которые представляют всю мощь программирования на shell. И их функционал достаточен практически для любого ряда задач. Повторяю еще раз, читаемость кода ни столько заслуга самого языка, а сколько того, кто на нем пишет. На любом языке(кроме гик-язкыков) можно писать как понятно, так и нет. Надеюсь примеров приводить Вам не нужно.

Про синтаксис и квадратные скобочки — не смешите, если Вы настолько приверженец c-based синтаксиса, то от python Вас просто должно воротить.

(for (xxx in yyy) {}) — пишется два цикла и все.

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

Но личный опыт мне подсказывает, что мне бы было удобнее писать многие вещи всё же на Python, чем когда я их писал на sh.

Предлагаю спор закончить на этом, я вашу точку зрения понял, и даже готов признать что выражение «Любые вещи, делаются на том же Python гораздо приятнее» неуместно.
>В вашем примере используется awk, с каких пор awk является частью sh?
а так же ls, cat, grep, cut, cd, ln, chmod, echo, time, false, dd… это же все на С написано и давно скомпилировано!!! срочно убрать из всех скриптов!!!1стоадинацать
Кстати замечание ваше на тему того, что awk — не часть shell'а не вполне уместно. Вот версия того, что ubique, как я полагаю, хотел написано (а написал он нечто неработающее во-первых и не имеющее смысла во-вторых):
$ while IFS=':' read I J K r; do if ((K>1000)); then echo "$I"; fi; done < /etc/passwd | sort -r
sort — это часть coreutils без которых bash использовать заруднительно. Работает? Да. Коротко? Несомнено. Сам чёрт ногу в этом сломает? Разумеется.
про awk, это я к тому сказал, что в Убунту (не знаю как там в настоящих дебианах) awk не входит в комплект того, что ставится в систему по умолчанию. Тут даже пакета 2 разных mawk и gawk.
cat /etc/passwd | awk -F ':' ' $3 >1000 {print $1}' | sort -r

Вот что я имел ввиду, просто было поздно.

В моем выражении черт ногу не сломит, а в Вашем — да. Полагаю Вы согласитесь с тем, что «черт ногу сломит» зависит только от того, кто пишет. И не более.
В моем выражении черт ногу не сломит, а в Вашем — да.
В вашем понять что-либо ничуть не легче, поверьте. Особенно человеку не очень хорошо знающему awk. Тот факт что я с первой попытки написал работающую версию, а вы со второй — тоже говорит о многом.

Перестаньте цепляться к опискам. Это не делает Вам чести.
Полагаю Вы согласитесь с тем, что «черт ногу сломит» зависит только от того, кто пишет.
Не только. Важно ещё кто читает. Для меня версия с ипользованием bash'а без awk читается проще, к тому же она расширяется легче.
А если Вы не уловили смысла — то это список пользовательских аккаунтов, не системных :)
Неправда. У меня, например, nobody имеет номер 65534 — но да, я примерно так и понял: мой скрипт и ваш второй выдают список пользователей зарегистрированных через /etc/passwd (а это, понятно, не все пользователи) с UID больше 1000 (то есть одного нормального пользователя они таки теряют). И то что в вашем втором скрипте содежится пара ошибок как раз и указывает на то, что подобные трюки больше годятся на то, чтобы поражать неискушённых, чем на то, чтобы ими реально можно было пользоваться. Процедура написанная и отлаженная на python'е будет писаться дольше, но есть шанс что она будет правильной. А подобный «грязный хак» легко написать прямо в командной строке, получить неверный результат и потом долго пытаться понять — в чём, собственно, беда…
>зарегистрированных через /etc/passwd (а это, понятно, не все пользователи)
приведите пример

Стандартный пул пользовательских uid'ов начинается с 1000.
Это не грязный хак, это реальное использование unix систем, и если Вы не умеете использовать базовые утилиты и каждый раз городите свой велосипед на языка программирования — Вы не понимаете UNIX.
>зарегистрированных через /etc/passwd (а это, понятно, не все пользователи)
приведите пример
Ну вот, например, с машины на которой я сейчас сижу:
$ cat /etc/passwd | awk -F ':' ' $3 >1000 {print $1}' | sort -r
nobody
$ id -u
13197
Причём всё же очевидно (мне даже в голову не пришло что про подобный вариант «развития событий» нужно говорить явно):
$ cat /etc/pam.d/common-auth
auth sufficient pam_unix.so
auth sufficient pam_krb5.so retain_after_close forwardable refresh_creds use_first_pass
auth required pam_deny.so
И после этого вы ещё рассуждаете о больших системах? Смешно.
Стандартный пул пользовательских uid'ов начинается с 1000.
Обычно, но не всегда.
Это не грязный хак, это реальное использование unix систем, и если Вы не умеете использовать базовые утилиты и каждый раз городите свой велосипед на языка программирования — Вы не понимаете UNIX.
Как видим на моём примере — это таки грязный хак. Список пользователей вообще не должен жить (и не живёт) в /etc/passwd, а для управления пользователями есть специальные утилиты.
Кроме пользователя nobody еще какие-то есть?
Я просил привести аналог для поиска в /etc/passwd, никакие другие механизмы атворизации(like kerberos) я не затрагивал. Примера Вашего я не увидел. Привести его сможете?
Shell — стандарт серверных скриптов и слава богу — к сожалению, python'y до этого еще далеко.

То, что вы привели — это то, что я могу набрать в командной строке для однократного пользования. Если же это приходится делать часто, то я предпочту скрипт на 10 строк на Python'е или даже, прости господи, на Perl'е. Просто потому что их будет приятнее читать.

А ставить на каждый сервер Python — почему бы и нет? Он не так много места занимет. Ибо как вы сами заметили bash без кучи дополнительных примочек вообще нифига не умеет, а Python во многом самодостаточен. Нужны только совсем системно-зависимые команды (типа modprobe).

Если же вам не нужно программировать (ну совсем простая система — роутер какой-нибудь), то к вашим услугам nash. А bash жив только за счёт того, что от вредных привычек сложно избавляться. И мне в том числе. Но пропогандировать его…
Согласен с вами, сам использую для этого javascript, со всей его мощью и интерпретатором jsdb.
Куму интересно, то вот линк на него
Да какие примочки? Любой shell сценарий использует base утилиты из системы. И для тех задач, которые решаются shell-сценариями их хватает с избытком.
Любой shell сценарий использует base утилиты из системы.
1. awk далеко не во всех системах входит в base system, так что вы сами себе противоречите своим примером.
2. Cравните суммарный вес этих утилит плюс bash'а и python'а. Разница будет невелика и ещё не факт что проиграет python.
3. В том-то и дело что их «хватает с избытком» — нужно держать в голове кучу бессмысленных сведений чтобы читать чужие скрипты, но для нормального программирования bash всё равно не годится.

Мне кажется правильное воприятие всего этого: bash — неизбежное зло.
Во всех production системах awk входит в base-system.
Python — слишком сырой и использовать его для простых серверных скриптов может только фанатик.
Если Вы не знаете базовых утилит unix — Вам лучше с ним распрощаться навсегда. Вам было бы полезно ознакмоиться с идеологией UNIX. Могу посоветовать книгу Эрика Рэймонда — «Искусство программирования в UNIX».
Во всех production системах awk входит в base-system.
О как. Вот прямо даже так. То есть все системы где нет awk автоматически объявляются не-production?
Python — слишком сырой и использовать его для простых серверных скриптов может только фанатик.
И в чём же заключается его сырость?
Если Вы не знаете базовых утилит unix — Вам лучше с ним распрощаться навсегда. Вам было бы полезно ознакмоиться с идеологией UNIX. Могу посоветовать книгу Эрика Рэймонда — «Искусство программирования в UNIX»
А с чего вы решили что я ней не знаком? И что эту книгу я не читал? Или любой человек, прочитавший её и не воспылавший нежной любовью к awk автоматически записывается в душевнобольные?
Нет. На сервера принято ставитьтолько production системы, и всякие экзотические дистрибутивы к ним не относятся. А во всех боевых дистрибутивах awk есть.
Сырость заключается хотя бы в полной несовеместимости 2 и 3 ветки. Это достаточное условие.
С того, что Вы не понимаете или не хотите призновать того, что в ней говориться.
Нет. На сервера принято ставитьтолько production системы, и всякие экзотические дистрибутивы к ним не относятся. А во всех боевых дистрибутивах awk есть.
Кем принято? Когда принято? Почему принято? Что такое «боевой» дистрибутив?
Сырость заключается хотя бы в полной несовеместимости 2 и 3 ветки. Это достаточное условие.
О как. То есть любая система, которая развивается (ну например bash, совместимость первой и второй версий оставляет желать лучшего) для production систем не годится. Хм… А что там вообще может быть установлено.
С того, что Вы не понимаете или не хотите призновать того, что в ней говориться.
То есть любой человек, не согласный с выводами вашей «суперкниги» автоматически ничего не понимает в unix? Бред.
production системы(nix) — freebsd, и несколько дистрибутивов linux. Которые суммарно покрывают 98% серверных установок nix систем. Принятно ставить системными администраторами, которые имееют порядочный опыт работы.

Bash был всегда sh compatible. Во всяком случае bash скрипты спокойно читались. О полном различии не может быть и речи.

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

Вы книгу читали? Можете привести пункты, с которыми не согласны? И желательно аргументировать.
production системы(nix) — freebsd, и несколько дистрибутивов linux. Которые суммарно покрывают 98% серверных установок nix систем. Принятно ставить системными администраторами, которые имееют порядочный опыт работы.
Если мы говорим о типичных средних конторах — то, пожалуй, соглашусь. Но на них свет клином не сошёлся и понятие «production system» они таки не покрывают. Является ли система, выпускаемая десятками миллионов экземпляров (как какой-нибудь WiFi-роутер) production системой? Явлется ли BluGene/L production-системой? По-моему вы слишком сужаете рамки того, что вы называете «production системой».
Bash был всегда sh compatible. Во всяком случае bash скрипты спокойно читались. О полном различии не может быть и речи.
Наоборот: о 100% совместимости никогда не шло и речи. Например такая вещь как var2=$"$var1" превратилась в bash2 в var2=${!var1} — но при этом старый синтаксис перестал работать!
Использование развивающихся, сырых, не достаточно проверенных систем обычно не принятно на production системах.
Если это принять за аксиому, то стоит принять также и факт, что python — не является таковой. Среди тех «нескольких дистрибутивов linux», о которых вы говорили выше есть и такой зверь как RHEL (RedHat Enterprise Linux — или вы скажете что и им никто не пользуется?). Там большая часть утилит администрирования написана на Python'е.
Вы можете использовать их у себя на тестовых машинах, но не в продакшн. За примерами далеко ходить не стоит. Гонка за всем новым и современным зачастую ничего не приносит кроме энергии, потраченной на установку этого нового и решения проблем, принесеннымм этим новым. Повторяюсь, речь идет о production системах. У себя дома — можете городить что хотите.
Ух ты, сколько пафоса. Слова-то верные, но причём тут Python?
Вы книгу читали? Можете привести пункты, с которыми не согласны? И желательно аргументировать.
Например его утверждения про полезность текстовые конфиги и хранения данных в текстовых форматах — весьма спорно. Активное использование текстовых конфигов обозначает что вы будете иметь миллион парсеров, которые будут пытаться парсить одни и те же конфиги и наверняка по разному! Использование чего-нибудь вроде Protocol Buffers или Apache Thrift ничуть бы не усложнило работу с конфигами (если забыть про bash), но дало бы возможность обойтись меньгим количеством «велосипедов». К сожалению историю нельзя повернуть вспять…
Вы посмотрите на название поста, посмотрите на чем и для чего предполагается писать скрипты и поймете, что ни о чем другом речь и не шла.

RH под рукой нет, но вот
Fedora 9:
/usr/bin/perl 1
/bin/sh 703
/usr/bin/pulseaudio 1
/bin/csh 1
/bin/bash 656
Что-то я не вижу здесь python. Если Вы говорите про средства администрирования, like pw, useradd, passwd, etc — удивлю Вас, они обычно на c пишутся.

Если парсеры будут писать идиоты, то да — конфиги будут парситсья по разному. И лучше все таки тектовые конфиги. Оставьте Ваши мечты и посмотрите на самые популярные open source проекты. Какими конфиг. файлами они пользуются?

Пожалуйста, давайте прекратим нашу беседу. Правда, мне надоело тратить свое время в пустую.
Любой shell сценарий использует base утилиты из системы.
1. awk далеко не во всех системах входит в base system, так что вы сами себе противоречите своим примером.
2. Cравните суммарный вес этих утилит плюс bash'а и python'а. Разница будет невелика и ещё не факт что проиграет python.
Только не забывайте о том, что эти утилиты всегда есть в системе, а python нужно ставить дополнительно.
А это уже зависит кто и для чего делал систему…
Мне кажется Вы просто не имеете опыта работа с большим количеством серверов и не знаете реалий. Вашу точку зрения я понял, и пытаться Вас переубедить — бесполезно, тем более что позиция Ваша достаточно откровенно выглядит глупой. Спасибо за Ваши ответы.
Мне кажется Вы просто не имеете опыта работа с большим количеством серверов и не знаете реалий.
Ну… смотря что считать «большим количеством серверов». В системах, с которыми работал я обычно было 100-200 серверов (в последнее время я сталкиваюсь с системами в 5'000-10'000 серверов, но вынужден признать что awk там есть… хотя python используется чаще) и они часто использовали специально под них заточенные дистрибутивы (да почти всегда — не годятся распространённые дистрибутивы под такие задачи без «обработки напильником»).
Вашу точку зрения я понял, и пытаться Вас переубедить — бесполезно, тем более что позиция Ваша достаточно откровенно выглядит глупой.
Я всегда готов сменить точку зрения под давлением фактов, но вот как раз с ними-то у вас туго: я вижу кучу неверных утверждений, а не какие-то факты с которыми я был бы готов согласиться. Как-то: во всех production системах awk входит в base-system — неверно: я сам общался с системами где awk не было. Вполне production. Или:Сырость заключается хотя бы в полной несовеместимости 2 и 3 ветки. Это достаточное условие. Тоже бред: переход с Java 1.4 на Java 1.5 был довольно-таки болезненным и с совместимостью там были напряги. Что не мешает Java быть и оставаться одним из самых используемых на production системах языком. Ну и так далее.

Повторяюсь, я говорил лишь о том, что там где shell может решать задачу нужно использовать его, а не python. Я не говорю о том, чтобы писать биллинг на sh.
И если Вас не затруднит, расскажите пожалуйста, с какими система в 5000-10000 серверов Вы работаете.
Примеры моих неверных утверждений в студию. За исключением не верного варианта первого скрипта(о котором Вы не смогли устоять и сообщила аж целых два раза) и моего утверждения про пробел, не имеющего фактической смысловой нагрузки.

Хотя бы потому, shell скрипты быстрее python аналогов. Примеры сможете привести, для чего использовался python на этих серверах?
Примеры production систем, где нет awk привести можете?
Про java — говорим о python, так говорим о python.
Хотя бы потому, shell скрипты быстрее python аналогов. Примеры сможете привести, для чего использовался python на этих серверах?
Shell скрипты, как правило, медленнее python аналогов. А уж при использовании RPC (а как вы ещё собираетесь управлять кластером в несколько тысяч компьютеров?) из bash'а — это превращается в такой кошмар, что говорить о скорости их написания не приходится.
Примеры production систем, где нет awk привести можете?
Легко — любой WiFi router. Обычно там нет и python'а, но если вам нужен не один роутер, а система из нескольких сотен подобных зверей разбросанных по всему миру… в общем по-моему вы очень узко смотрите на понятие «production system».
Да как медленее? Пример — shell быстрее распарсит и посчитает статистику по какому-нибудь лог файлу. Вы так и не сказлаи для чего используется этот python на серверах. Назовите пожалуйста. Мы говорим о серверах — так о серверах, не изменяйте понятия.
обожаю bash отличная статься!!!

ps вобще-то не обязательно указывать первой строкой путь к интерпретатору (это относится не только к башу). это необходимо, если интерпретатор не указывается явно при запуске
Статья полезная, буду читать, но опечатки нужно исправить, очень портят впечатление. Обычный спеллчекер найдет массу перепутанных и пропущенных букв.
Мощю юникса не столько в его командных оболочках, сколько в его утилитах, и конвеерах.
Новичкам, на мой взгляд, гораздо полезнее и интересней узнать не о переменных баша, а о конструкциях с find, grep, и т.д.
Ого! Не одного комментария типа «а я думал статья про башорг о_О».
Ого! Ни одного комментария типа «ого, ни одного комментария типа \»а я думал статья про башорк\""…
Чёрт, уже один есть.
И даже webserver напитьсать)
>> Таким образом оператогр условия имеют следующий вид:
>> if [[ «что-то» <оператор логического сравнения «с чем-то»]]

Это не совсем верно, вернее совсем не верно.
[[ expression ]] — это встроенная команда bash, возвращающая 0 или 1 в зависимости от того что с условиями в скобках творится. Можно использовать и в отрыве от if:

diesel@indie:/home$ [[ `pwd` =~ «diesel» ]] && echo OK || echo «Not OK»
Not OK
diesel@indie:/home$ cd
diesel@indie:~$ [[ `pwd` =~ «diesel» ]] && echo OK || echo «Not OK»
OK

с другой стороны, if, как написано в man bash имеет формат:
if list; then list; [ elif list; then list; ]… [ else list; ] fi
где первый list исполняется и в зависимости от кода возврата будет выполнятся та или иная ветка условного оператора. То есть можно и вот так:

diesel@indie:~$ if ls / > /dev/null 2> /dev/null ;then echo ok; else echo «not ok»; fi
ok
diesel@indie:~$ if ls /no-such-dir > /dev/null 2> /dev/null ;then echo ok; else echo «not ok»; fi
not ok

if [ expression ]; then или if [[ expression ]]; then — просто часто употребляются вместе, но if и [[ это две самостоятельные команды.
и чем мой код «совсем не верен»? Просто я считаю [[ ]] более универсальной структурой, и для понимания работы оператора if-then-else незачем захламлять текст(и мозги читателей) другими способами сравнения условий.
потому как if [[ ]] не является цельной структурой, — это две разных команды. это важно для понимания того что происходит.

> if-then-else незачем захламлять текст(и мозги читателей) другими способами сравнения условий.

в том то и дело что if не является командой для «сравнения условий». if является командой которая смотрит на код возврата команды, которую вы указываете собственно после if. и [[ ]] — просто самая популярная команда, которую часто подставляют — это не может быть более универсальной структурой по-определению, поскольку универсальность здесь как раз и состоит в том что за if может следовать любая другая команда.

В следующих статьях Вы пообещали рассказать про циклы, с тем же while ситуация абсолютно такая же как и с if. и если Вы расскажите о конструкциях типа:
ls | while read i; do do-smth-with-file "$i"; done
то это как раз будет ненужное захламление мозга шаблонами: в if мы можем только сравнивать, а в while подставлять команды, или сравнивать (хотя на самом деле «сравнивать» — изначально просто еще одна команда)
Да, теперь я понял о чем вы, я недостаточно точно выразился. Коментарий верен только для примера приведенного в статье. Статью дополню
конструкция [ "$a" > "$b" ] всегда возвращает true
подумайте над этим
ЗЫ: код верен, не верен комментарий.
Добавлю, что [[ — это т.н. башизм, тогда как test и [ — это встроенные в баш аналоги утилит из coreutils (в Linux). Т.о., использование [[ автоматически делает скрипт непортабельным.
Да, [[ лучше использовать только тогда, когда действительно оно надо, то есть делается что-то чего [/test не умеет(например, [[ вроде как умеет регулярные выражения ). Впрочем, башизм это — не плохо. Плохо это когда в bash-скрипте стоит #!/bin/sh, и зависимостей от bash нет.
т.е. вы хотите сказать, что если я использую [[, то такой скрипт не будет работать, скажем под *BSD? При условии что на linux и *bsd вресии bash одни.
Да будет конечно. Если там bash есть.
Многие не дооценивают удобство и простоту баша. Главное, не пытаться писать «монструозные» скрипты и всегда знать меру.

Хочется сказать, что даже на баш скрипты можно и нужно писать тесты.

Например, написать тесты можно очень просто с помощью bashtest утилиты.
Тесты выглядят как примеры запуска. Примеры тестов можно найти в гитхабе проекта.
Sign up to leave a comment.

Articles