cp /etc/foo .
echo "Готово".
else # Файл не существует, поэтому мы печатаем сообщение
# и завершаем работу
echo "Этот файл не существует."
exit
fi
Обратите внимание на отступы строки после then и else. Они не являются обязательными, но зато делают чтение кода гораздо более простым в том смысле, что делают логику программы более наглядной. Теперь запустите программу. Если у вас есть файл /etc/foo — он будет скопирован, в противном случае будет напечатано сообщение об ошибке. Команда test проверяет существование файла. Ключ -f проверяет, является ли аргумент обычным файлом. Ниже приведен список опций test[7]:
Ключи команды test:
-d проверяет наличие файла и то, что он является каталогом
-e проверяет существование файла
-f проверяет наличие файла и то, что это обычный файл
-g проверяет наличие у файла SGID-бита
-r проверяет наличие файла и то, что он доступен на чтение
-s проверяет наличие файла и то, что его размер больше нуля
-u проверяет наличие у файла SUID-бита
-w проверяет наличие файла и то, что он доступен на запись
-x проверяет наличие файла и наличие у него прав на запуск
Оператор else используется, когда вы хотите, чтобы ваша программа еще что-то делала, если первое условие не выполняется. Существует также оператор elif, который может использоваться вместо еще одного if.elif означает «else if». Он используется, когда первое условие не выполняется, и вы хотите проверить еще одно условие.
Если вам не нравится приведенная форма записи if и test, есть сокращенный вариант.
Например, код:
if test -f /etc/foo
then
Можно записать вот так:
if [ -f /etc/foo ]; then
Квадратные скобки — это еще один вариант записи test. Если у вас есть опыт в программировании на C, этот синтаксис для вас может быть более удобным. Обратите внимание на наличие пробелов до и после каждой из скобок test[8]. Точка с запятой: «;» говорит оболочке о завершении одного оператора и начале следующего. Все, что находится после этого символа будет работать так, как будто он находится на отдельной строке. Это делает код более удобным для чтения и, естественно, что такая запись необязательна. Если вы предпочитаете другой вариант записи —then можно сразу поместить в другой строке.
Если вы используете переменные — их нужно помещать в кавычки. Например:
if [ "$name" -eq 5 ]; then
оператор -eq будет объяснен далее в этой статье.
while … do … done
Оператор while используется для организации циклов. Он работает так «пока (while) условие истинно, делать что-то». Рассмотрим это на примере:
#!/bin/bash
while true; do
echo "Нажмите CTRL-C для выхода."
done
true — это тоже программа. Единственное, что она тут делает — это запускает тело цикла снова и снова. Использование true считается медленным, потому что ваш скрипт должен запускать ее раз за разом. Можно использовать альтернативный вариант:
#!/bin/bash
while :; do
echo "Нажмите CTRL-C для выхода."
done
Это позволяет добиться точно такого же эффекта, но быстрее, потому что «:» — это встроенная функция bash. Единственное отличие состоит в принесении в жертву читабельности кода. Используйте из приведенных вариантов тот, который вам нравится больше. Ниже приведен гораздо более полезный вариант использования переменных:
#!/bin/bash
x=0;
while [ "$x" -le 10 ]; do
echo "Текущее значение х: $х"
# Увеличиваем значение х:
x=$(expr $x + 1)
sleep 1
done
Здесь мы используем для проверки состояния переменной x запись с квадратными скобками. Опция -le означает «меньше или равно (less or equal)». Говоря обычным языком приведенный код говорит: «пока (while) х меньше или равен 10, выводить на экран текущее значение х, после чего добавлять к текущему значению х единицу». Оператор sleep 1 приостанавливает выполнение программы на одну секунду.
Ниже приведен список возможных операций сравнения целых чисел[9]:
x -eq y x = y (equal)
x -ne y x не равен y (not equal)
x -gt y x больше, либо равен y (greater than)
x -lt y x меньше, либо равен y (lesser than)
Операторы сравнения строк:
x = y строка x идентична y
x != y строка х не совпадает y
-n x выражение истинно, если строка х ненулевой длины
-z x выражение истинно, если строка х имеет нулевую длину
Скрипт, приведенный выше, нетрудно понять, за исключением, может быть, только этой строки:
x=$(expr $x + 1)
Комментарий приведенный выше он говорит нам, что он увеличивает х на 1. Но что означает запись$ (...)? Это переменная? Нет. На самом деле это способ сказать оболочке, что вы хотите запустить команду expr $x + 1, и присвоить результат ее выполнения — х. Любая команда, заключенная в $ (…) будет выполняться:
#!/bin/bash
me=$(whoami)
echo "Привет! Меня зовут $me"
Попробуйте сделать приведенный пример, и вы поймете, что я имею в виду. Приведенный выше код можно было бы сократить без каких-либо потерь вот так:
#!/bin/bash
echo "Привет! Меня зовут $(whoami)"
Вы сами можете выбрать, какая из записей вам ближе и понятнее. Существует и другой способ для выполнения команд или передачи результата их выполнения переменной. Как это сделать — будет объяснено позже. Пока используйте запись вида $(…).
until … do … done
Оператор until применяет способом аналогичным приведенному выше while. Разница лишь в том, что условие работает наоборот. Цикл while выполняет до тех пор пока условие истинно. Цикл until — до тех пор пока условие не станет истинным. Например:
#!/bin/bash
x=0
until [ "$x" -ge 10 ]; do
echo "Текущее значение х равно $ х"
x=$(expr $x + 1)
sleep 1
done
Эта часть кода выглядит знакомой. Попробуйте ее набрать и посмотреть, что он делает. Приведенный цикл будет работать, пока x не станет больше или равен 10. Когда величина x достигнет значения 10, цикл остановится. Таким образом, последнее значение напечатанное значение х будет 9.
for … in … do … done
Цикл for используется, когда вам надо перебрать несколько значений переменной. Например, вы можете написать небольшую программу, которая печатает 10 точек:
#!/bin/bash
echo -n "Проверка системы на наличие ошибок"
for dots in 1 2 3 4 5 6 7 8 9 10; do
echo -n "."
done
echo "Ошибок не обнаружено"
Опция -n команды echo предотвращает автоматический перевод строки. Попробуйте один раз вариант с -n и вариант без этой опции, чтобы понять, что я имею в виду. Переменная dots последовательно принимает значения от 1 до 10 и одновременно скрипт печатает на экране точку.
7
Не стоит пытаться запомнить их все, т.к. это все равно нереально. Его всегда можно посмотреть в руководстве команды test - man test. (Прим. перев.)
8
Наличие пробелов объясняется просто: открывающая квадратная скобка - это команда оболочки. В этом можно легко убедиться набрав в консоли команду which [ . А раз это отдельная команда, то ее нужно отделить пробелами от остальных опций. (прим. перев.)