Bash by example / Bash в примерах: Part 2: More bash programming fundamentals
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Передача аргументов командной строки Daemon786 24.01.11 в 15:02 |
|
|
Для начала, небольшой совет по использованию аргументов командной строки - а потом мы рассмотрим основные состовляющие Баша. icori 22.01.11 в 08:45 Мы начнем с маленькой подсказки об использовании аргументов командной строки, а потом рассмотрим основные конструкции языка программирования Баша. mslasm 27.01.11 в 19:34 |
+1 | |
|
В примере, даннов во введении, мы использовали переменную окружения "$1", которая указывает на первый аргумент командной строки. Точно так же, можно использовать "$2", "$3", и т.д. чтобы указать на второй и третий аргумент, данный вашему скрипту. Вот пример: icori 22.01.11 в 08:50 В простой программе из вступительной статьи мы использовали переменную окружения "$1", которая ссылается на первый аргумент командной строки. Аналогично вы можете использовать "$2", "$3" и т.д., чтобы указать на второй и третий аргументы, переданные вашему сценарию. Вот пример: Daemon786 24.01.11 в 13:46 |
||
|
#!/usr/bin/env bash Daemon786 21.01.11 в 08:10 |
||
|
Пример говорит сам за себя, за исключением трех маленьких деталей. Во-первых, "$0" выведет имя сценария, которое указано при вызове из командной строки, а "$#" укажет количество аргументов переданных сценарию. Использование фигурных скобок является необязательным для однозначных номеров, но необходимо для аргументов выше "$9". Поиграйте с приведенным сценарием, подставляя различные аргументы командной строки, чтобы запомнить как это работает. Daemon786 24.01.11 в 14:31 |
||
|
Иногда удобно обозначить сразу все аргументы командной строки. Для этого используется переменная "$@", которая объединит в себе все параметры командной строки, разделенные пробелами. Мы увидим пример ее использования чуть позже в этой статье, когда будем рассматривать циклы "for". Daemon786 24.01.11 в 15:01 |
||
|
Управляющие конструкции в bash Daemon786 24.01.11 в 15:50 |
||
|
Если вы программировали на процедурных языках, таких как C, Pascal, Python или Perl, то вы хорошо знакомы с такими управляющими конструкциями как операторы "if", циклы "for" и тому подобные. Bash имеет свои собственные версии большинства из этих стандартных конструкций. В следующих разделах я расскажу о нескольких управляющих конструкциях и продемонстрирую их отличия от их аналогов в других известных вам языках программирования. Если вы не имеете опыта программирования, не волнуйтесь. Я включил достаточно информации и примеров, чтобы вы смогли следить за текстом. Daemon786 24.01.11 в 15:50 |
||
|
Любовь к условиям undeceived 30.01.11 в 16:08 |
||
|
Если вам когда-либо приходилось писать код для работы с файлами на С, то вы знаете, что для того, чтобы сравнить даты создания двух файлов требуется приложить значительное количество усилий. Так происходит потому, что в языке С нету встроенных средств для подобных сравнений; и вот приходится делать два вызова stat(), использовать две структуры stat и делать сравнения вручную. Напротив, в bash уже имеются встроенные средства для работы с файлами и, таким образом, проверка "имеется ли доступ на чтение к файлу /tmp/myfile" не сложнее проверки "значение переменной $myvar больше 4?". undeceived 30.01.11 в 15:57 |
||
|
В таблице ниже приведен список наиболее часто используемых операций сравнения в bash. Также в ней вы найдете примеры правильного использования каждой операции. undeceived 30.01.11 в 16:00 |
||
|
if [ -z "$myvar" ] Daemon786 21.01.11 в 08:11 |
||
|
В некоторых случаях существует несколько способов осуществления необходимой проверки. В качестве примера рассмотрим два фрагмента кода ниже, которые реализуют одну и ту же функциональность: undeceived 30.01.11 в 16:02 |
||
|
if [ "$myvar" -eq 3 ] Daemon786 21.01.11 в 08:11 |
||
|
Хотя оба примера выше и выполяют одно и то же действие, но разница заключается в том, что в первом используется арифметическая операция сравнения, а во втором - строковая. undeceived 30.01.11 в 16:08 |
||
|
Замечания о сравнении строк. undeceived 30.01.11 в 16:09 |
||
|
В большинстве случаев можно не помещать строковые переменные в двойные кавычки, но это не слишком хорошая практика. Почему? Потому что ваш код будет работать правильно до тех пор, пока в строковой переменной не появится символы пробела или табуляции. В таком случае bash придет в некоторое замешательство. Вот пример хренового сравнения: undeceived 30.01.11 в 16:12 В большинстве случаев можно не помещать строковые переменные в двойные кавычки, но это не слишком хорошая практика. Почему? Потому что ваш код будет работать правильно до тех пор, пока в строковой переменной не появится символы пробела или табуляции. В таком случае bash придет в некоторое замешательство. Вот пример никуда ни годного сравнения: Daemon786 06.02.11 в 20:30 |
||
|
if [ $myvar = "foo bar oni" ] Daemon786 21.01.11 в 08:12 |
||
|
В данном примере, если значение myvar равно "foo" - код будет работать правильно и ничего не напечатает. Однако, если значение myvar равно "foo bar oni" - при исполнении код выдаст ошибку: undeceived 30.01.11 в 16:13 |
||
|
[: too many arguments Daemon786 21.01.11 в 08:12 |
||
|
В данном случае пробелы внутри значения переменной $myvar (значение которой равно "foo bar oni") приведут к тому, что bash не будет знать как сравнивать значения. После того, как bash подставит значение переменной $myvar операция сравнения будет выглядеть так: undeceived 30.01.11 в 16:16 |
||
|
[ foo bar oni = "foo bar oni" ] Daemon786 21.01.11 в 09:03 |
||
|
Так как переменная не была помещена внутри двойных кавычек - bash решит, что вы передали слишком много аргументов внутри квадратных скобок. Эту проблему легко решить поместив переменную в двойные кавычки. undeceived 30.01.11 в 16:18 |
||
|
if [ "$myvar" = "foo bar oni" ] Daemon786 21.01.11 в 09:03 |
||
|
Данный пример всегда будет работать так, как задумано и позволит избежать каких-либо неприятных сюрпризов. undeceived 30.01.11 в 16:19 |
||
|
Примечание: undeceived 30.01.11 в 16:21 Примечание: undeceived 30.01.11 в 16:21 |
+2 | |
|
Циклические конструкции: "for" Daemon786 21.01.11 в 09:46 |
||
|
Итак, мы рассмотрели условные операторы, а теперь пришло время разобраться с конструированием циклов в bash. Начнем мы со стандартного цикла "for". undeceived 30.01.11 в 16:23 |
||
|
#!/usr/bin/env bash Daemon786 21.01.11 в 09:04 |
||
|
Давайте разберемся что тут произошло. undeceived 30.01.11 в 16:32 |
||
|
#!/usr/bin/env bash Daemon786 21.01.11 в 09:05 |
||
|
Приведенный выше код перебирает все файлы в каталоге /etc, которые начинаются с "r". Для того, чтобы это сделать перед выполнением цикла bash сначала заменил "/etc/r*" на соответствующие этому шаблону строку /etc/rc.d /etc/resolv.conf /etc/resolv.conf~ /etc/rpc. undeceived 30.01.11 в 16:41 |
||
|
Также вы можете использовать несколько шаблонов или даже переменных при указании списка слов: undeceived 30.01.11 в 16:42 |
||
|
for x in /etc/r??? /var/lo* /home/drobbins/mystuff/* /tmp/${MYPATH}/* Daemon786 21.01.11 в 09:06 |
||
|
Bash будет выполнят подстановку значений по шаблону и значения переменной окружения во всех нужных местах и, возможно, создаст очень длинный список слов. Daemon786 01.02.11 в 09:46 |
||
|
Пока все наши примеры подстановок по шаблону имели абсолютные пути, но вы можете также использовать относительные пути, а именно: Daemon786 01.02.11 в 09:37 |
||
|
for x in ../* mystuff/* Daemon786 21.01.11 в 09:06 |
||
|
В приведенном выше примере bash выполняет раскрытие шаблонов относительно текущей рабочей директории, также как вы используете относительные пути в командной строке. Поэкспериментируйте немного с подстановкой по шаблону. Вы заметите, что если использовать абсолютные пути, то bash раскроет шаблон в список с абсолютными путями. В противном случае bash будет использовать относительные пути в последующем списке слов. Если вы просто ссылаетесь на файлы в своей рабочей директории (например, вы ввели for x in *), результирующий список файлов не будет начинаться с какой либо информации о пути. Помните, что информация о пути может быть удалена использованием basename, как показано ниже: Daemon786 01.02.11 в 12:55 |
||
|
for x in /var/log/* Daemon786 21.01.11 в 09:06 |
||
|
Конечно, часто удобно для выполнения циклов работать с аргументами командной строки сценария. Вот пример того, как использовать переменную "$@", представленную в начале этой статьи. Daemon786 01.02.11 в 12:58 |
||
|
#!/usr/bin/env bash Daemon786 21.01.11 в 09:07 |
||
|
Арифметические операции в оболочке Daemon786 21.01.11 в 09:45 |
||
|
Прежде чем обратить внимание на второй тип циклических конструкций, было бы неплохо ознакомиться с выполнением арифметических операций в оболочке. Да, это правда: вы можете выполнять простые математические операции с целыми числами, используя конструкции оболочки. Просто поместите арифметическое выражение между "$((" и "))", и bash вычислит его. Вот несколько примеров: Daemon786 01.02.11 в 15:50 |
||
|
$ echo $(( 100 / 3 )) Daemon786 21.01.11 в 09:07 |
||
|
Теперь, когда вы познакомились с выполнением математических операций, настало время представить две другие циклические конструкции в bash, "while" и "until". Daemon786 01.02.11 в 15:56 |
||
|
Больше циклических конструкций: "while" и "until" Daemon786 01.02.11 в 13:12 |
||
|
Оператор "while" выполняется до тех пор, пока условие истинно, и имеет следующий вид: Daemon786 02.02.11 в 15:38 |
||
|
while [ условие ] Daemon786 21.01.11 в 09:12 while [ условие ] bugzy 28.02.11 в 14:42 |
||
|
Оператор "while" используется, как правило, для выполнения цикла определенного количества раз, как в следующем примере, в котором цикл будет выполнен ровно 10 раз: Daemon786 03.02.11 в 14:58 |
||
|
myvar=0 Daemon786 21.01.11 в 09:07 |
