number=$(($$ % $biggest) # Случайное число от 1 до $biggest
Исправим эту ошибку, добавив закрывающую круглую скобку в конец выражения, но перед комментарием. А теперь игра заработает? Давайте попробуем:
$ hilow
Guess? 33
… bigger!
Guess? 66
… bigger!
Guess? 99
… bigger!
Guess? 100
… bigger!
Guess? ^C
Почти получилось. Но при попытке ввести максимально возможное значение 100 появляется ответ, что загаданное число больше (bigger), значит, в логике игры допущена ошибка. Искать такие ошибки особенно сложно, потому что никакая, даже самая замысловатая команда grep или sed не поможет выявить проблему. Вернитесь к коду и попробуйте найти ошибку самостоятельно.
Чтобы упростить поиск, можно добавить несколько команд echo, вывести значение, выбранное пользователем, и проверить, какое число введено и какое проверяется. Соответствующий раздел кода начинается в строке , но для удобства приведем эти строки еще раз:
/bin/echo −n "Guess?"; read answer
if ["$guess" −lt $number]; then
Изменив команду echo и исследовав эти две строки, мы заметили ошибку: ввод пользователя читается в переменную answer, а проверяется переменная guess. Глупая, но не такая уж редкая ошибка (особенно если имеются переменные с необычными для вас именами). Чтобы исправить ошибку, нужно заменить read answer на read guess.
Результаты
Наконец сценарий работает правильно, как показано в листинге 1.31.
Листинг 1.31. Сценарий hilow работает без ошибок
$ hilow
Guess? 50
… bigger!
Guess? 75
… bigger!
Guess? 88
… smaller!
Guess? 83
… smaller!
Guess? 80
… smaller!
Guess? 77
… bigger!
Guess? 79
Right!! Guessed 79 in 7 guesses.
Усовершенствование сценария
Самая досадная ошибка, кроющаяся в этом маленьком сценарии, — отсутствие проверки ввода. Попробуйте ввести произвольную строку вместо числа, и сценарий завершится с сообщением об ошибке. Мы легко могли бы добавить элементарную проверку, включив следующие строки в цикл while:
if [-z "$guess"]; then
··echo "Please enter a number. Use ^C to quit"; continue;
fi
Но непустой ввод еще не означает, что введено число, и, если ввести произвольную сроку, например hi, сценарий все еще будет завершаться с ошибкой. Чтобы исправить эту проблему, добавьте вызов функции validint из сценария № 5.
Глава 2. Усовершенствование пользовательских команд
Типичная система Unix или Linux по умолчанию включает сотни команд, которые, с учетом многообразия флагов и способов сочетания команд посредством каналов, дают миллионы разных вариантов работы в командной строке.
Прежде чем двинуться дальше, взгляните на листинг 2.1, в котором приводится премиальный сценарий, подсчитывающий количество команд, доступных в списке каталогов PATH.
Листинг 2.1. Подсчет количества выполняемых и невыполняемых файлов в текущем списке PATH
#!/bin/bash
# Подсчет количества команд: простой сценарий для подсчета количества выполняемых
#·· команд в каталогах из списка PATH
IFS=":"
count=0; nonex=0
for directory in $PATH; do
··if [-d "$directory"]; then
····for command in "$directory"/*; do
······if [-x "$command"]; then
········count="$(($count + 1))"
······else
········nonex="$(($nonex + 1))"
······fi
····done
··fi
done
echo "$count commands, and $nonex entries that weren't executable"
exit 0
Этот сценарий подсчитывает не просто файлы, а выполняемые файлы, и может использоваться для оценки количества команд и невыполняемых файлов в каталогах из списка PATH в разных системах (табл. 2.1).
Операционная система | Команд | Невыполняемых файлов |
---|---|---|
Ubuntu 15.04 (включая все библиотеки для разработки) | 3156 | 5 |
OS X 10.11 (со всеми установленными инструментами для разработки) | 1663 | 11 |
FreeBSD 10.2 | 954 | 4 |
Solaris 11.2 | 2003 | 15 |