Командная строка Linux
Шрифт:
27. Управление потоком выполнения: ветвление при помощи if
В предыдущей главе мы столкнулись с проблемой. Как помочь сценарию адаптировать свое поведение в зависимости от привилегий пользователя, запустившего его? Для решения проблемы нам необходим некий способ «изменить направление» выполнения сценария, опираясь на результаты проверки. Выражаясь языком программистов, нам нужен способ, обеспечивающий ветвление программы.
Рассмотрим простой пример логики, выраженный в псевдокоде, имитирующем язык компьютеров,
x = 5
Если x = 5, тогда:
Сказать «x равно 5».
Иначе:
Сказать «x не равно 5».
Это — пример ветвления. Если условие «x = 5?» верно, выполняется строка: «Сказать ‘x равно 5’». Иначе выполняется строка: «Сказать ‘x не равно 5’».
Использование if
В сценариях на языке командной оболочки описанную выше логику можно реализовать так:
x=5
if [ $x = 5 ]; then
echo "x equals 5."
else
echo "x does not equal 5."
fi
А если то же самое можно выполнить непосредственно в командной строке, получается немного короче:
[me@linuxbox ~]$ x=5
[me@linuxbox ~]$ if [ $x = 5 ]; then echo "equals 5"; else echo "does not equal 5"; fi
equals 5
[me@linuxbox ~]$ x=0
[me@linuxbox ~]$ if [ $x = 5 ]; then echo "equals 5"; else echo "does not equal 5"; fi
does not equal 5
В этом примере мы выполнили команду дважды. Первый раз со значением 5 в переменной x, что привело к выводу строки equals 5, и второй раз со значением 0 в переменной x, что привело к выводу строки not equal 5.
Инструкция if имеет следующий синтаксис:
if команды; then
команды
[elif команды; then
commands...]
[else
команды]
fi
где команды — это список команд. На первый взгляд такой синтаксис выглядит запутанным. Но прежде чем прояснить его, посмотрим, как командная оболочка определяет, успешно или нет выполнена команда.
Код завершения
Команды (включая сценарии и функции, написанные нашими собственными руками) по завершении работы возвращают системе значение, которое называют кодом завершения (exit status). Это значение — целое число в диапазоне от 0 до 255 — сообщает об успешном или неуспешном завершении команды. По соглашениям значение 0 служит признаком успешного завершения, а любое другое — неуспешного. Командная оболочка поддерживает переменную, посредством которой можно определить код завершения. Например:
[me@linuxbox ~]$ ls -d /usr/bin
/usr/bin
[me@linuxbox ~]$ echo $?
0
[me@linuxbox ~]$ ls -d /bin/usr
ls: cannot access /bin/usr: No such file or directory
[me@linuxbox ~]$ echo $?
2
В этом примере мы дважды выполнили
Командной оболочкой поддерживаются две чрезвычайно простые встроенные команды, которые просто завершаются с кодом 0 или 1. Команда true всегда завершается с признаком успеха, а команда false — всегда с признаком ошибки:
[me@linuxbox ~]$ true
[me@linuxbox ~]$ echo $?
0
[me@linuxbox ~]$ false
[me@linuxbox ~]$ echo $?
1
Эти команды можно использовать для исследования особенностей работы инструкции if. Инструкция if в действительности просто оценивает код завершения команды:
[me@linuxbox ~]$ if true; then echo "It's true."; fi
It's true.
[me@linuxbox ~]$ if false; then echo "It's true."; fi
[me@linuxbox ~]$
Команда echo "It's true." выполняется, только если команда, следующая за if, завершается успешно, и не выполняется, если команда, следующая за if, завершается с признаком ошибки. Если за if следует список команд, успешность выполнения всего списка определяется по последней команде:
[me@linuxbox ~]$ if false; true; then echo "It's true."; fi
It's true.
[me@linuxbox ~]$ if true; false; then echo "It's true."; fi
[me@linuxbox ~]$
Команда test
Вне всяких сомнений, чаще всего с инструкцией if используется команда test. Команда test может выполнять различные проверки и сравнения. Она имеет две эквивалентные формы:
test выражение
и более популярную
[ выражение ]
где выражение возвращает истинное (true) или ложное (false) значение. Команда test возвращает код завершения 0, если выражение истинно, и код завершения 1, если выражение ложно.
Выражения для проверки файлов
В табл. 27.1 перечислены выражения, используемые для проверки файлов.
Таблица 27.1. Выражения для проверки файлов
Выражение
Истинно, если...
файл1 -ef файл2
файл1 и файл2 имеют одно и то же число индексного узла (inode; то есть два имени принадлежат жестким ссылкам, ссылающимся на один и тот же файл)
файл1 -nt файл2
файл1 новее файла файл2