Shell script — различия между версиями

Материал из pNp Wiki
Перейти к: навигация, поиск
(Вывод на экран)
(case)
 
(не показано 30 промежуточных версий этого же участника)
Строка 72: Строка 72:
 
[root@vm-01 ~]#
 
[root@vm-01 ~]#
 
</syntaxhighlight>
 
</syntaxhighlight>
Если необходимо вывести именно строку $PATH, то следует использовать символы экранирования (двойные кавычки <code>""</code>, одинарные кавычки <code>''</code>, либо обратный слэш <code>\</code>):
+
Если необходимо вывести именно строку $PATH, то следует использовать символы экранирования (двойные кавычки <code>"</code>, одинарные кавычки <code>'</code>, либо обратный слэш <code>\</code>):
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
[root@vm-01 ~]# cat test.sh  
 
[root@vm-01 ~]# cat test.sh  
Строка 85: Строка 85:
 
[root@vm-01 ~]#
 
[root@vm-01 ~]#
 
</syntaxhighlight>
 
</syntaxhighlight>
Следует заметить, что двойные кавчки экранируют не все спецсимволы, поэтому если необходимо вывести какую-либо информацию как текст, то следует использовать одинарные кавычки!
+
Следует заметить, что двойные кавчки экранируют не все спецсимволы, поэтому если необходимо вывести какую-либо информацию как текст, то следует использовать одинарные кавычки, которые интерпретируют
 +
любую включенную в них информацию как текст! Обратный слэш (<code>\</code>) экранирует только символ следующий за ним!
 +
 
 +
== Использование переменных ==
 +
Переменная - это область памяти, которая хранит некое значение. К этой области памяти можно обращаться по имени. Название переменной не может начинаться с цифры! Например:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
 
 +
one=1
 +
echo "This is number $one"
 +
 +
[root@vm-01 ~]# ./test.sh
 +
This is number 1
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
Хорошим тоном считается заключать значения, присваиваемые переменными в двойные кавычки, к примеру, потому, что в значении могут содержаться пробелы, а пробелы интерпретируются
 +
<code>bash</code>'ем как разделитель слова. Так же, хорошим тоном считается заключение переменных в фигурные скобки, так как переменные могут конкатенироваться непосредственно
 +
друг за другом, поэтому, во избежании получения неожиданных результатов, переменные следует записывать как <code>${one}</code>.
 +
Пример конкатенцации переменных:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
 
 +
one="1"
 +
two="2"
 +
echo "This is number twelve: ${one}${two}"
 +
 
 +
[root@vm-01 ~]# ./test.sh
 +
This is number twelve: 12
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
 
 +
== Расширения командного интерпретатора ==
 +
Кроме переменных, <code>bash</code> позволяет использовать подстановку команд и арифметические операции
 +
 
 +
==== Подстановка команд ====
 +
Подстановка команд осуществляется путем помещения команды в обратные кавычки <code>`</code>, либо путем указания переменной в круглых скобках <code>()</code>. Например:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
cli="`which bash`"
 +
curl="$(which curl)"
 +
echo "My bash is here: ${cli} and curl is here: ${curl}"
 +
[root@vm-01 ~]# ./test.sh
 +
My bash is here: /usr/bin/bash and curl is here: /usr/bin/curl
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
Второй способ предпочтительнее, так как он поддерживает вложенность команд. Например:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
count="$($(which ls) -l *.conf | $(which wc) -l)"
 +
echo "Amount of conf files in /root directory: ${count}"
 +
 
 +
[root@vm-01 ~]# ./test.sh
 +
Amount of conf files in /root directory: 4
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
==== Арифметика ====
 +
Арифметические операции осуществляются путем помещения команды в квадратные скобки (<code>[]</code>), которым предшествует знак <code>$</code>. Например:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
count1=$[ 3 * 3 ]
 +
count2=$[2+2]
 +
echo "${count1}"
 +
echo "${count2}"
 +
 
 +
[root@vm-01 ~]# ./test.sh
 +
9
 +
4
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
Часто применяемые арифметические действия и их значения
 +
{| class="wikitable"
 +
|-
 +
! Оператор !! Значение
 +
|-
 +
| <переменная>++ || постинкремент переменной
 +
|-
 +
| <переменная>-- || постдекремент переменной
 +
|-
 +
| ++<переменная> || преинкремент переменной
 +
|-
 +
| --<переменная> || предекремент переменной
 +
|-
 +
| - || вычитание, унарный минус
 +
|-
 +
| + || сложение, унарный плюс
 +
|-
 +
| ** || возведение в степень
 +
|-
 +
| * || умножение
 +
|-
 +
| / || деление
 +
|-
 +
| % || остаток от деления
 +
|-
 +
|}
 +
Если в арифметическом выражении есть несколько действий, то <code>bash</code> выполняет такие операции в соответствии с правилами математики.
 +
Таблица приоритета арифметических действий:
 +
 
 +
{| class="wikitable"
 +
|-
 +
! Оператор !! Значение
 +
|-
 +
| <переменная>++, <переменная>-- || постинкремент и постинкремент переменных
 +
|-
 +
| ++<переменная>, --<переменная> || преинкремент и предекремент переменных
 +
|-
 +
| -, + || унарный минус и плюс
 +
|-
 +
| ** || возведение в степень
 +
|-
 +
| *, /, % || умножение, деление, остаток от деления
 +
|-
 +
| +, - || сложение, вычитание
 +
|}
 +
 
 +
== Циклы bash ==
 +
 
 +
Для повторяемых действий в <code>bash</code> имеются циклы <code>for</code>, <code>while</code> и <code>until</code>
 +
==== Использование цикла for ====
 +
Синтаксис цикла выглядит следующим образом:
 +
<syntaxhighlight lang="bash">
 +
for переменная in список; do команды; done
 +
</syntaxhighlight>
 +
Например:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
 
 +
count=0
 +
 
 +
for i in $(ls /root/*.conf); do
 +
    count=$[count+1]
 +
    echo "${count}"
 +
done
 +
[root@vm-01 ~]# ./test.sh
 +
1
 +
2
 +
3
 +
4
 +
[root@vm-01 ~]
 +
</syntaxhighlight>
 +
 
 +
== Специальные переменные bash ==
 +
{| class="wikitable"
 +
|-
 +
! Переменная !! Значение
 +
|-
 +
| $? || код завершения программы (как правило: 0 - успешное завершение, все отилчное от 0 - ошибка)
 +
|-
 +
| $0 || имя самой программы
 +
|-
 +
| $1..$9 || аргументы скрипта
 +
|-
 +
| $@ || список аргументов ($1,$2,$3..)
 +
|-
 +
| $* || список аргументов, рассматриваемых как единый аргумент ("$1 $2 $3..")
 +
|-
 +
| $# || количество переданных аргументов
 +
|}
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
 
 +
count="$#"
 +
 
 +
for i in "$@"; do
 +
    echo "Current argument is: $i"
 +
    echo "Total amount of args: ${count}"
 +
    echo "Whole arg string: $*"
 +
done
 +
[root@vm-01 ~]# ./test.sh 1 2 3 4 5 6 7 8 9
 +
Current argument is: 1
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
Current argument is: 2
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
Current argument is: 3
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
Current argument is: 4
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
Current argument is: 5
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
Current argument is: 6
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
Current argument is: 7
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
Current argument is: 8
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
Current argument is: 9
 +
Total amount of args: 9
 +
Whole arg string: 1 2 3 4 5 6 7 8 9
 +
[root@vm-01 ~]# echo $?
 +
0
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
== Сравнения ==
 +
Для сравнения переменных в <code>bash</code>, используется либо команда <code>test</code>, либо внутренние команды <code>[[]]</code>.
 +
 
 +
==== Числовые сравнения ====
 +
 
 +
{| class="wikitable"
 +
|-
 +
! Оператор !! Значение !! Пример
 +
|-
 +
| -eq || равно || [ "$a" -eq "$b" ]
 +
|-
 +
| -ne || неравно || [ "$a" -ne "$b" ]
 +
|-
 +
| -gt || больше чем || [ "$a" -gt "$b" ]
 +
|-
 +
| -ge || больше или равно || [ "$a" -ge "$b" ]
 +
|-
 +
| -lt || меньше чем || [ "$a" -lt "$b" ]
 +
|-
 +
| -le || меньше или равно || [ "$a" -le "$b" ]
 +
|}
 +
 
 +
==== Строковые сравнения ====
 +
 
 +
{| class="wikitable"
 +
|-
 +
! Оператор !! Значение !! Пример
 +
|-
 +
| = || равно || [ "$a" = "$b" ]
 +
|-
 +
| == || равно || [ "$a" == "$b" ]
 +
|-
 +
| != || неравно || [ "$a" != "$b" ]
 +
|-
 +
|}
 +
 
 +
==== Логические операторы AND и OR ====
 +
 
 +
{| class="wikitable"
 +
|-
 +
! Оператор !! Значение
 +
|-
 +
| && || Следующая команда выполняется только, если результат предыдущий был успешен (истина)
 +
|-
 +
| <nowiki>||</nowiki> || Следующая команда выполняется, если результат предыдущий был неуспешен (ложь)
 +
|}
 +
 
 +
== Условия ==
 +
==== if/then ====
 +
Общие правила построения условий <code>if/then</code> условий:
 +
 
 +
<syntaxhighlight lang="bash">
 +
if условие; then
 +
  действие
 +
  действие
 +
  ...
 +
fi
 +
</syntaxhighlight>
 +
Например:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
 
 +
count="$#"
 +
 
 +
if [ "$count" -gt 1 ]; then
 +
    echo "Number of args greater than one"
 +
fi
 +
 
 +
for i in "$@"; do
 +
    echo "Current argument is: $i"
 +
    echo "Total amount of args: ${count}"
 +
    echo "Whole arg string: $*"
 +
done
 +
 
 +
exit 0
 +
[root@vm-01 ~]# ./test.sh
 +
[root@vm-01 ~]# ./test.sh 1
 +
Current argument is: 1
 +
Total amount of args: 1
 +
Whole arg string: 1
 +
[root@vm-01 ~]# ./test.sh 1 2
 +
Number of args greater than one
 +
Current argument is: 1
 +
Total amount of args: 2
 +
Whole arg string: 1 2
 +
Current argument is: 2
 +
Total amount of args: 2
 +
Whole arg string: 1 2
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
 
 +
==== if/then/else ====
 +
Общие правила построения условий <code>if/then/else</code> условий:
 +
 
 +
<syntaxhighlight lang="bash">
 +
if условие; then
 +
  действие
 +
  действие
 +
  ...
 +
else
 +
  действие
 +
  действие
 +
  ...
 +
fi
 +
</syntaxhighlight>
 +
Например:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
 
 +
count="$#"
 +
 
 +
if [ "$count" == 0 ]; then
 +
    echo "You did not enter any args!"
 +
    exit 1
 +
else
 +
 
 +
for i in "$@"; do
 +
    echo "Current argument is: $i"
 +
    echo "Total amount of args: ${count}"
 +
    echo "Whole arg string: $*"
 +
done
 +
fi
 +
 
 +
exit 0
 +
[root@vm-01 ~]# ./test.sh
 +
You did not enter any args!
 +
[root@vm-01 ~]# echo $?
 +
1
 +
[root@vm-01 ~]# ./test.sh 0 1
 +
Current argument is: 0
 +
Total amount of args: 2
 +
Whole arg string: 0 1
 +
Current argument is: 1
 +
Total amount of args: 2
 +
Whole arg string: 0 1
 +
[root@vm-01 ~]# echo $?
 +
0
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
 
 +
==== if/then/elif/then/else ====
 +
Расширение условия выглядит следующим образом:
 +
 
 +
<syntaxhighlight lang="bash">
 +
if условие; then
 +
  действие
 +
  действие
 +
  ...
 +
elif условие; then
 +
  действие
 +
  действие
 +
  ...
 +
else
 +
  действие
 +
  действие
 +
  ...
 +
fi
 +
</syntaxhighlight>
 +
Например
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
 
 +
count="$#"
 +
 
 +
if [ "$count" == 0 ]; then
 +
    echo "You did not enter any args!"
 +
    exit 1
 +
elif [ "$count" -gt 5 ]; then
 +
    echo "You have entered too many args!"
 +
    exit 2
 +
else
 +
 
 +
for i in "$@"; do
 +
    echo "Current argument is: $i"
 +
    echo "Total amount of args: ${count}"
 +
    echo "Whole arg string: $*"
 +
done
 +
fi
 +
 
 +
exit 0
 +
[root@vm-01 ~]# ./test.sh
 +
You did not enter any args!
 +
[root@vm-01 ~]# ./test.sh 1 2 3 4 5 6
 +
You have entered too many args!
 +
[root@vm-01 ~]# ./test.sh 1 2 3 4 5
 +
Current argument is: 1
 +
Total amount of args: 5
 +
Whole arg string: 1 2 3 4 5
 +
Current argument is: 2
 +
Total amount of args: 5
 +
Whole arg string: 1 2 3 4 5
 +
Current argument is: 3
 +
Total amount of args: 5
 +
Whole arg string: 1 2 3 4 5
 +
Current argument is: 4
 +
Total amount of args: 5
 +
Whole arg string: 1 2 3 4 5
 +
Current argument is: 5
 +
Total amount of args: 5
 +
Whole arg string: 1 2 3 4 5
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
Хоть и конструкций <code>elif</code> может быть сколько угодно, не рекомендуется прибегать к их большому количеству,
 +
так как это ухудшает читабельность кода.
 +
==== case ====
 +
Вместо <code>elif</code>, в тех случаях, когда требуется обширная логика условий, следует
 +
применять <code>case</code>
 +
<syntaxhighlight lang="bash">
 +
case значение in
 +
  условие1)
 +
        действие
 +
        действие
 +
        ...
 +
        ;;
 +
  условие2)
 +
        действие
 +
        действие
 +
        ...
 +
        ;;
 +
  *)
 +
        действие
 +
        действие
 +
        ...
 +
        ;;
 +
 
 +
esac
 +
</syntaxhighlight>
 +
Условие <code>*)</code> означает "во всех остальных случаях". Пример:
 +
<syntaxhighlight lang="bash">
 +
[root@vm-01 ~]# cat test.sh
 +
#!/bin/bash
 +
 
 +
case "$1" in
 +
 
 +
      "0")
 +
      echo "It is a zero!: $1"
 +
      ;;
 +
     
 +
      "100")
 +
      echo "Wow! You have entered: $1"
 +
      ;;
 +
 
 +
      *)
 +
      if [ -z "$1" ]; then
 +
            echo "You have entered nothing"
 +
            exit 1
 +
      else
 +
            echo "You have entered: $1 "
 +
      fi
 +
      ;;
 +
 
 +
 
 +
esac
 +
 
 +
exit 0
 +
[root@vm-01 ~]# ./test.sh
 +
You have entered nothing
 +
[root@vm-01 ~]# ./test.sh 2
 +
You have entered: 2
 +
[root@vm-01 ~]# ./test.sh 0
 +
It is a zero!: 0
 +
[root@vm-01 ~]# ./test.sh 100
 +
Wow! You have entered: 100
 +
[root@vm-01 ~]#
 +
</syntaxhighlight>
 +
 
 +
== Ссылки ==
 +
[http://www.lib.ru/unixhelp/unixshell.txt Интерпретатор командного языка shell]<br />
 +
[https://www.lissyara.su/doc/programming/shell/ Программирование на языке командного интерпретатора - shell]<br />
 +
[https://ru.wikipedia.org/wiki/Bash Bash]<br />
 +
[http://tldp.org/LDP/abs/html/ Advanced Bash-Scripting Guide]<br />

Текущая версия на 12:37, 4 апреля 2018

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

Предварительные требования

  • Виртуальная машина с двумя сетевыми интерфейсами
  • Установленные пакеты: bash, bash-completion, vim-minimal, vim-enhanced

Общая информация

Любой скрипт, начинается с "магической строки" - сигнатуры, которая говорит командному интерпретатору как обрабатывать файл. Для скриптов, такая последовательность носит называние she-bang (сокращение от sharp-bang):

#!

Соответственно, если файл должен обрабатывать bash, то это необходимо указать после "магической строки". То есть, she-bang будет иметь следующий вид:

#!/bin/bash

Если скрипт предназначен для пользователя, то должны быть выставлен необходимый владелец файла, и права на запуск скрипта 755. Поскольку скрипт является выполняемым, то по первым литерам названия, коммандный интерпертатор производит поиск названия в переменной $PATH, соответственно, лучше выбрать имя для скрипта, которое не совпадает с имеющейся утилитой. Для просмотра переменной $PATH надо выполнить следующую команду:

[root@vm-01 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@vm-01 ~]#

Поскольку текущая директория /root отсутствует в переменной $PATH, то запускать скрипты необходимо следующим образом:

[root@vm-01 ~]# ls -lahi test.sh 
33969143 -rwxr-xr-x. 1 root root 34 Mar 26 10:38 test.sh
[root@vm-01 ~]# ./test.sh 
Hello, world!
[root@vm-01 ~]#

Вывод на экран

Скрипт test.sh использует комманду echo для отображения текстовой строки. По-умолчанию отображение производится на стандартный поток вывода (STDOUT):

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

echo "Hello, world!"
[root@vm-01 ~]#

Хорошим тоном считается выводить ошибки на поток ошибок (STDERR):

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

echo "Hello, world!"
echo "Something has happend! Can not proceed!" >&2
[root@vm-01 ~]#

Запустим скрипт таким образом, что бы поток ошибок направлялся в файл:

[root@vm-01 ~]# ./test.sh 2>test.log
Hello, world!
[root@vm-01 ~]# cat test.log 
Something has happend! Can not proceed!
[root@vm-01 ~]#

При выводе на экран, следует учесть, что некоторые символы могут иметь специальное значение, в следствие чего, использование таких символов может привести к результатам отличным от ожидаемого. Например, если необходимо узнать содержимое PATH, то следует написать так:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

echo "$PATH"
[root@vm-01 ~]# ./test.sh 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@vm-01 ~]#

Если необходимо вывести именно строку $PATH, то следует использовать символы экранирования (двойные кавычки ", одинарные кавычки ', либо обратный слэш \):

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

echo "\$PATH"
echo '$PATH'

[root@vm-01 ~]# ./test.sh 
$PATH
$PATH
[root@vm-01 ~]#

Следует заметить, что двойные кавчки экранируют не все спецсимволы, поэтому если необходимо вывести какую-либо информацию как текст, то следует использовать одинарные кавычки, которые интерпретируют любую включенную в них информацию как текст! Обратный слэш (\) экранирует только символ следующий за ним!

Использование переменных

Переменная - это область памяти, которая хранит некое значение. К этой области памяти можно обращаться по имени. Название переменной не может начинаться с цифры! Например:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

one=1
echo "This is number $one"
 
[root@vm-01 ~]# ./test.sh 
This is number 1
[root@vm-01 ~]#

Хорошим тоном считается заключать значения, присваиваемые переменными в двойные кавычки, к примеру, потому, что в значении могут содержаться пробелы, а пробелы интерпретируются bash'ем как разделитель слова. Так же, хорошим тоном считается заключение переменных в фигурные скобки, так как переменные могут конкатенироваться непосредственно друг за другом, поэтому, во избежании получения неожиданных результатов, переменные следует записывать как ${one}. Пример конкатенцации переменных:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

one="1"
two="2"
echo "This is number twelve: ${one}${two}"

[root@vm-01 ~]# ./test.sh 
This is number twelve: 12
[root@vm-01 ~]#

Расширения командного интерпретатора

Кроме переменных, bash позволяет использовать подстановку команд и арифметические операции

Подстановка команд

Подстановка команд осуществляется путем помещения команды в обратные кавычки `, либо путем указания переменной в круглых скобках (). Например:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash
cli="`which bash`"
curl="$(which curl)"
echo "My bash is here: ${cli} and curl is here: ${curl}" 
[root@vm-01 ~]# ./test.sh 
My bash is here: /usr/bin/bash and curl is here: /usr/bin/curl
[root@vm-01 ~]#

Второй способ предпочтительнее, так как он поддерживает вложенность команд. Например:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash
count="$($(which ls) -l *.conf | $(which wc) -l)"
echo "Amount of conf files in /root directory: ${count}"

[root@vm-01 ~]# ./test.sh 
Amount of conf files in /root directory: 4
[root@vm-01 ~]#

Арифметика

Арифметические операции осуществляются путем помещения команды в квадратные скобки ([]), которым предшествует знак $. Например:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash
count1=$[ 3 * 3 ]
count2=$[2+2]
echo "${count1}"
echo "${count2}"

[root@vm-01 ~]# ./test.sh 
9
4
[root@vm-01 ~]#

Часто применяемые арифметические действия и их значения

Оператор Значение
<переменная>++ постинкремент переменной
<переменная>-- постдекремент переменной
++<переменная> преинкремент переменной
--<переменная> предекремент переменной
- вычитание, унарный минус
+ сложение, унарный плюс
** возведение в степень
* умножение
/ деление
 % остаток от деления

Если в арифметическом выражении есть несколько действий, то bash выполняет такие операции в соответствии с правилами математики. Таблица приоритета арифметических действий:

Оператор Значение
<переменная>++, <переменная>-- постинкремент и постинкремент переменных
++<переменная>, --<переменная> преинкремент и предекремент переменных
-, + унарный минус и плюс
** возведение в степень
*, /, % умножение, деление, остаток от деления
+, - сложение, вычитание

Циклы bash

Для повторяемых действий в bash имеются циклы for, while и until

Использование цикла for

Синтаксис цикла выглядит следующим образом:

for переменная in список; do команды; done

Например:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

count=0

for i in $(ls /root/*.conf); do 
    count=$[count+1]
    echo "${count}"
done
[root@vm-01 ~]# ./test.sh 
1
2
3
4
[root@vm-01 ~]

Специальные переменные bash

Переменная Значение
$? код завершения программы (как правило: 0 - успешное завершение, все отилчное от 0 - ошибка)
$0 имя самой программы
$1..$9 аргументы скрипта
$@ список аргументов ($1,$2,$3..)
$* список аргументов, рассматриваемых как единый аргумент ("$1 $2 $3..")
$# количество переданных аргументов
[root@vm-01 ~]# cat test.sh 
#!/bin/bash

count="$#"

for i in "$@"; do
    echo "Current argument is: $i"
    echo "Total amount of args: ${count}"
    echo "Whole arg string: $*"
done
[root@vm-01 ~]# ./test.sh 1 2 3 4 5 6 7 8 9
Current argument is: 1
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
Current argument is: 2
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
Current argument is: 3
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
Current argument is: 4
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
Current argument is: 5
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
Current argument is: 6
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
Current argument is: 7
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
Current argument is: 8
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
Current argument is: 9
Total amount of args: 9
Whole arg string: 1 2 3 4 5 6 7 8 9
[root@vm-01 ~]# echo $?
0
[root@vm-01 ~]#

Сравнения

Для сравнения переменных в bash, используется либо команда test, либо внутренние команды [[]].

Числовые сравнения

Оператор Значение Пример
-eq равно [ "$a" -eq "$b" ]
-ne неравно [ "$a" -ne "$b" ]
-gt больше чем [ "$a" -gt "$b" ]
-ge больше или равно [ "$a" -ge "$b" ]
-lt меньше чем [ "$a" -lt "$b" ]
-le меньше или равно [ "$a" -le "$b" ]

Строковые сравнения

Оператор Значение Пример
= равно [ "$a" = "$b" ]
== равно [ "$a" == "$b" ]
 != неравно [ "$a" != "$b" ]

Логические операторы AND и OR

Оператор Значение
&& Следующая команда выполняется только, если результат предыдущий был успешен (истина)
|| Следующая команда выполняется, если результат предыдущий был неуспешен (ложь)

Условия

if/then

Общие правила построения условий if/then условий:

if условие; then
   действие
   действие
   ...
fi

Например:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

count="$#"

if [ "$count" -gt 1 ]; then
    echo "Number of args greater than one"
fi

for i in "$@"; do
    echo "Current argument is: $i"
    echo "Total amount of args: ${count}"
    echo "Whole arg string: $*"
done

exit 0
[root@vm-01 ~]# ./test.sh
[root@vm-01 ~]# ./test.sh 1
Current argument is: 1
Total amount of args: 1
Whole arg string: 1
[root@vm-01 ~]# ./test.sh 1 2
Number of args greater than one
Current argument is: 1
Total amount of args: 2
Whole arg string: 1 2
Current argument is: 2
Total amount of args: 2
Whole arg string: 1 2
[root@vm-01 ~]#

if/then/else

Общие правила построения условий if/then/else условий:

if условие; then
   действие
   действие
   ...
else 
   действие
   действие
   ...
fi

Например:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

count="$#"

if [ "$count" == 0 ]; then
    echo "You did not enter any args!" 
    exit 1
else

for i in "$@"; do
    echo "Current argument is: $i"
    echo "Total amount of args: ${count}"
    echo "Whole arg string: $*"
done
fi

exit 0
[root@vm-01 ~]# ./test.sh 
You did not enter any args!
[root@vm-01 ~]# echo $?
1
[root@vm-01 ~]# ./test.sh 0 1
Current argument is: 0
Total amount of args: 2
Whole arg string: 0 1
Current argument is: 1
Total amount of args: 2
Whole arg string: 0 1
[root@vm-01 ~]# echo $?
0
[root@vm-01 ~]#

if/then/elif/then/else

Расширение условия выглядит следующим образом:

if условие; then
   действие
   действие
   ...
elif условие; then 
   действие
   действие
   ...
else 
   действие
   действие
   ...
fi

Например

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

count="$#"

if [ "$count" == 0 ]; then
    echo "You did not enter any args!" 
    exit 1
elif [ "$count" -gt 5 ]; then
    echo "You have entered too many args!"
    exit 2
else

for i in "$@"; do
    echo "Current argument is: $i"
    echo "Total amount of args: ${count}"
    echo "Whole arg string: $*"
done
fi

exit 0
[root@vm-01 ~]# ./test.sh
You did not enter any args!
[root@vm-01 ~]# ./test.sh 1 2 3 4 5 6
You have entered too many args!
[root@vm-01 ~]# ./test.sh 1 2 3 4 5 
Current argument is: 1
Total amount of args: 5
Whole arg string: 1 2 3 4 5
Current argument is: 2
Total amount of args: 5
Whole arg string: 1 2 3 4 5
Current argument is: 3
Total amount of args: 5
Whole arg string: 1 2 3 4 5
Current argument is: 4
Total amount of args: 5
Whole arg string: 1 2 3 4 5
Current argument is: 5
Total amount of args: 5
Whole arg string: 1 2 3 4 5
[root@vm-01 ~]#

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

case

Вместо elif, в тех случаях, когда требуется обширная логика условий, следует применять case

case значение in
   условие1)
        действие
        действие
        ...
        ;;
   условие2)
        действие
        действие
        ...
        ;;
   *)
        действие
        действие
        ...
        ;;

esac

Условие *) означает "во всех остальных случаях". Пример:

[root@vm-01 ~]# cat test.sh 
#!/bin/bash

case "$1" in

      "0")
      echo "It is a zero!: $1"
      ;;
      
      "100")
      echo "Wow! You have entered: $1"
      ;;

      *)
      if [ -z "$1" ]; then
            echo "You have entered nothing"
            exit 1
      else
            echo "You have entered: $1 "
      fi
      ;;


esac

exit 0
[root@vm-01 ~]# ./test.sh
You have entered nothing
[root@vm-01 ~]# ./test.sh 2
You have entered: 2 
[root@vm-01 ~]# ./test.sh 0
It is a zero!: 0
[root@vm-01 ~]# ./test.sh 100
Wow! You have entered: 100
[root@vm-01 ~]#

Ссылки

Интерпретатор командного языка shell
Программирование на языке командного интерпретатора - shell
Bash
Advanced Bash-Scripting Guide