Shell script — различия между версиями
Andy (обсуждение | вклад) |
Andy (обсуждение | вклад) (→case) |
||
(не показаны 22 промежуточные версии этого же участника) | |||
Строка 159: | Строка 159: | ||
[root@vm-01 ~]# | [root@vm-01 ~]# | ||
</syntaxhighlight> | </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