К постам Опубликовано: 2016-09-05

Основы языка bash, bash скрипты, bash команды.

Сценарии командной оболочки широко используются в мире UNIX.
Они отлично подходят для ускорения повторяющихся задач и упростить сложную логику выполнения. Они могут быть столь же просты, как набор команд, или же они могут организовать сложные задачи. Мы узнаем больше, написав пример bash-скрипта, шаг за шагом. Для выполнения скрипта интерпретатором нужно указать в самом начале:
#!/путь/к/интерпретатору 
Интерпретатор это программа, которая используется для интерпретации нашего языка. Баш интерпретатор находяться в  /bin/bash, на linux mint, да и в большинстве остальных linux дистрибутивов. Например, если вы хотите создать скрипт в PHP и запустить его в консоли, вы, можете использовать
/usr/bin/php
(или путь к исполняемому файлу PHP на вашем компьютере) в качестве интерпретатора.
#!/usr/bin/php

phpinfo();
И правда просто, не так ли? Для того что бы быть уверенным в работе скрипта на стольких системах на скольких это возможно, вместо /bin/bash, можно использовать  /bin/env: [code]/bin/env bash[/code]

Вывод текста

Если мы явно хотим, написать что-то на экране, мы можем использовать [code]echo[/code].

[code]
#!/bin/bash

echo "Hello World"
[/code]
  Данный скрипт выведет в консоли следующее:

[code]
dimonchoo@dimonchoo ~ $ ./helloWorld.sh
Hello World
dimonchoo@dimonchoo ~ $
[/code]

Вступление в переменные.

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

[code]
#!/bin/bash

message="Hello World"
echo $message
[/code]

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

Выведем числа от 1 до 100

Для этой задачи используем цикл for:

[code]
#!/bin/bash

for number in {1..100}; do
    echo $number
done
[/code]

Синтаксис команды for в Bash: for Переменная in Диапазон; do Команда done.
Скобки переводят значение между ними в диапазон.
For и do две разные команды, если вы хотите их отделить визуально, то можете перенести на новую строку.
[code]
#!/bin/bash
fornumber in{1..100}
do
    echo$number
done
[/code]
Принимаем решение.

[code]
#!/bin/bash

for number in {1..100}; do
    if [ $((number%3)) -eq 0 ]; then
        echo "Fizz"
    else
        echo $number
    fi
done
[/code]

if..then..else..fi - классический синтаксис условияif в Bash. Конечно, часть else опциональна - но необходима для нашего логического условия.
if COMMAND-RETURN-VALUE; then... -  Чтобы упростить вещи: все, кроме 0вернетfalse.
Математические выражения в Bash устанавливаются с помощью двойных скобок. $((number%3))вернут значение деления переменной, числа, на 3. Запомните что мы не используем $ в середине родительских скобок - только снаружи.
Еще

[code]
#!/bin/bash

for number in {1..100}; do
    if [ $((number%3)) -eq 0 ]; then
        echo "Fizz"
    elif [ $((number%5)) -eq 0 ]; then
        echo "Buzz"
    else
        echo $number
    fi
done
[/code]

Выше, мы ввели другое условие для деления на 5: elif условие. Это, конечно, можно перевести как else if, и будет извлечено если команда возвращает true (или 0). Как вы могли заметить, условные выражения из [] обычно применяют из вспомогательными параметрами, такие как-eq, что означает "равняется."
Также существуют другие арифметические параметры -ne, -lt, -le, -gt, или -ge.

Если вам нужно сравнить строки, вы должны использовать == знак. != возвратит true когда строки будут разными.

Используем метод для логического выражения

Один из путей усовершенствования нашего выражения можно через if условие, как то так:
[code]
#!/bin/bash

function isDivisibleBy {
    return $(($1%$2))
}

for number in {1..100}; do
    output=""
    if isDivisibleBy $number 3; then
        output="Fizz"
    fi
    if isDivisibleBy $number 5; then
        output="${output}Buzz"
    fi
    if [ -z $output ]; then
        echo $number
    else
        echo $output;
    fi
done
[/code]
Мы взяли выражения, сравнивающие остальные с нуля, и переместили их в функцию. Более того, мы устранили сравнение с нулем, потому что ноль означает true для нас. Мы только возвратили значение из математического выражения - очень просто!
Заметка: Оглашение функции должно быть перед ее вызовом.
В Bash, вы можете задать метод как function название_функции { команды; }. Опционально, есть еще второй синтаксис для оглашения функции: имя_функции () { команды; }. Вы не должны определять параметры для функций в Bash. Передача параметров в функции осуществляется путем простого перечисления над ними после вызова функции, разделенных пробелами. Не помещайте запятые или круглые скобки в вызов функции - это не будет работать. Полученные параметры автоматически присваиваются переменным в числовом порядке. Первый параметр переходит к $1, второй в $2, и так далее. Специальная переменная $0 означает имя файла текущего сценария.
Давайте поиграемся с параметрами

[code]
#!/bin/bash

function exampleFunc {
    echo $1
    echo $0
    IFS="X"
    echo "$@"
    echo "$*"
}

exampleFunc "one" "two" "three"
[/code]
Этот код покажет нам следующиее:
[code]
dimonchoo@dimonchoo ~ $ ./parametersExamples.sh
one
./parametersExamples.sh
one two thre
oneXtwoXthre
[/code]
Давайте проанализируем код, строка за строкой.
Последняя строка это вызов функции. Мы вызываем ее с тремя параметрами типа строка.
Первая строка после строки вызова интерпретатора - оглашение функции.
Первая строка в функции выводит первый параметр: "one". И так дальше.
Вторая строка выводит имя данного скрипта. Опять, просто.
Третья строка изменяет типичные разделители символов на букву, "X". Стандартно разделитель, " " (пробел). Вот как Bash знает как параметры разделены.
Четвертая строка выводит специальную переменную, $@. Она представляет все параметры как единое слово, в особенности как зазначено в вызове функции.
Финальная строка выводит еще одну специальную переменную, $*. Она представляет все параметры, взятые одна за одной и конкатенированы с первой буквой переменной IFS. Вот почему результат oneXtwoXthre.
;, && and ||

&& используется между двумя командами. Да, это логическое AND (И); Это означает что вторая команда исполнится только тогда, когда первая команда вернет true . Это полезно; [code] #!/bin/bash

function isDivisibleBy {
    return $(($1%$2))
}

function fizzOrBuzz {
    output=""
    isDivisibleBy $1 3 && output="Fizz"
    isDivisibleBy $1 5 && output="${output}Buzz"
    if [ -z $output ]; then
        echo $1
    else
        echo $output;
    fi
}

for number in {1..100}; do
    echo "-`fizzOrBuzz $number`"
done
[/code]

Подобным образом, мы можем использовать ||как логический OR. Пример:
[code]
dimonchoo@dimonchoo ~ $ echo "bubu" || echo "bibi"
bubu
dimonchoo@dimonchoo ~ $ echo false || echo "bibi"
false
dimonchoo@dimonchoo ~ $
[/code]