Дейв Тейлор - Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание
- Название:Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание
- Автор:
- Жанр:
- Издательство:Питер
- Год:2017
- Город:СПб.
- ISBN:978-5-496-03029-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дейв Тейлор - Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание краткое содержание
Цель этой книги — продемонстрировать практические приемы программирования сценариев на bash и познакомить с самыми распространенными утилитами на коротких и компактных примерах, не вдаваясь в излишние подробности. Экспериментируйте с этими сценариями — ломайте, исправляйте и приспосабливайте их под свои нужды, чтобы понять, как они работают. Только так вы сможете решать самые сложные задачи.
Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Несмотря на жутковатую идею, игра в «виселицу» давно стала классикой. Вы пытаетесь угадать, какие буквы есть в задуманном слове, и каждый раз, когда вы ошибаетесь, у человечка на виселице дорисовывается очередная часть тела. Когда ошибок оказывается слишком много, появляется полное изображение, что означает проигрыш и… как вы понимаете, смерть человечка. Довольно безжалостная игра!
Однако сама по себе игра довольно забавная, а ее реализация в виде сценария командной оболочки оказывается на удивление простой, как демонстрирует листинг 12.3. Вам также потребуется список слов, использовавшийся в сценарии № 83: сохраните файл long-words.txt из ресурсов книги в каталоге /usr/lib/games .
Код
Листинг 12.3.Игровой сценарий hangman
#!/bin/bash
# hangman — простая версия игры "виселица". Вместо постепенного рисования
#·· человечка он просто ведет обратный отсчет ошибочных попыток.
#·· В единственном необязательном аргументе сценарий принимает начальное
#·· расстояние до эшафота.
wordlib="/usr/lib/games/long-words.txt"
empty="\." # Нам нужно что-то для sed [set], когда $guessed="".
games=0
# Сначала проверить наличие библиотеки слов — файла wordlib.
if [! -r "$wordlib"]; then
··echo "$0: Missing word library $wordlib" >&2
··echo "(online: http://www.intuitive.com/wicked/examples/long-words.txt" >&2
··echo "save the file as $wordlib and you're ready to play!)" >&2
··exit 1
fi
# Большой цикл while. Здесь все и происходит.
while ["$guess"!= "quit"]; do
··match="$(randomquote $wordlib)" # Выбрать новое слово из библиотеки.
··if [$games −gt 0]; then
····echo ""
····echo "*** New Game! ***"
··fi
··games="$(($games + 1))"
··guessed=""; guess=""; bad=${1:-6}
··partial="$(echo $match | sed "s/[^$empty${guessed}]/-/g")"
··# В этом блоке производится:
··#·· ввод буквы > анализ > вывод результатов > переход к началу.
··while ["$guess"!= "$match" −a "$guess"!= "quit"]; do
····echo ""
····if [! -z "$guessed"]; then·· #! —z означает "непустое значение".
······/bin/echo −n "guessed: $guessed, "
····fi
····echo "steps from gallows: $bad, word so far: $partial"
····/bin/echo −n "Guess a letter: "
····read guess
····echo ""
····if ["$guess" = "$match"]; then # Угадано!
······echo "You got it!"
····elif ["$guess" = "quit"]; then # Запрошен выход? Хорошо.
······exit 0
····# Теперь нужно проверить присутствие введенной буквы в слове.
····elif [$(echo $guess | wc −c | sed 's/[^[: digit: ]]//g') −ne 2]; then
······echo "Uh oh: You can only guess a single letter at a time"
····elif [! -z "$(echo $guess | sed 's/[[: lower: ]]//g')"]; then
······echo "Uh oh: Please only use lowercase letters for your guesses"
····elif [-z "$(echo $guess | sed "s/[$empty$guessed]//g")"]; then
······echo "Uh oh: You have already tried $guess"
····# Теперь можно проверить присутствие буквы в слове.
····elif ["$(echo $match | sed "s/$guess/-/g")"!= "$match"]; then
······guessed="$guessed$guess"
······partial="$(echo $match | sed "s/[^$empty${guessed}]/-/g")"
······if ["$partial" = "$match"]; then
········echo "** You've been pardoned!! Well done! The word was \"$match\"."
········guess="$match"
······else
········echo "* Great! The letter \"$guess\" appears in the word!"
······fi
····elif [$bad −eq 1]; then
······echo "** Uh oh: you've run out of steps. You're on the platform…"
······echo "** The word you were trying to guess was \"$match\""
······guess="$match"
····else
······echo "* Nope, \"$guess\" does not appear in the word."
······guessed="$guessed$guess"
······bad=$(($bad — 1))
····fi
··done
done
exit 0
Как это работает
Все проверки в этом сценарии достаточно интересны, чтобы исследовать их подробнее. Взгляните на строку , которая проверяет, не ввел ли пользователь больше одного символа.
Почему в сравнении используется число 2, а не 1? Потому что к предложенной пользователем букве в результате нажатия клавиши Enterдобавляется символ перевода строки (\n). То есть правильно, когда строка содержит два символа, а не один. Команда sed в этой инструкции отбрасывает все нецифровые символы, чтобы исключить любые проблемы с начальными символами табуляции, которые так любит добавлять команда wc.
Проверка принадлежности к нижнему регистру в строке проста и понятна. Здесь удаляются все буквы нижнего регистра, и результат проверяется на равенство пустой строке.
Наконец, чтобы увидеть, предлагал ли уже пользователь эту букву: содержимое guess преобразуется так, что из него удаляются все буквы, присутствующие в переменной guessed. Затем проверяется, получилась ли в результате пустая строка .
Кроме всех этих проверок в сценарии hangman используется еще одна хитрость: в исходном слове все буквы, совпадающие с введенной, заменяются дефисами. Затем результат сравнивается с исходным словом . Если они различаются (то есть если одна или несколько букв заменены дефисами), значит, предложенная пользователем буква есть в слове. Например, если для загаданного слова cat пользователь ввел букву a , она будет записана в переменную guessed, которая получит значение '-a-'.
Одна из ключевых идей, лежащих в основе сценария hangman, — вывод частично угаданного слова из переменной partial, значение которой повторно собирается с каждой угаданной буквой. Поскольку в переменной guessed накапливаются буквы, угаданные игроком, команда sed преобразует в дефисы все буквы в исходном слове, которые отсутствуют в строке guessed .
Запуск сценария
Игра «виселица» принимает один необязательный аргумент: переданное ей число используется как максимально допустимое число ошибочных попыток, в противном случае их будет шесть (значение по умолчанию). В листинге 12.4 демонстрируется пример запуска сценария hangman без аргументов.
Результаты
Листинг 12.4.Сеанс игры «виселица»
$ hangman
steps from gallows: 6, word so far: —-
Guess a letter: e
* Great! The letter "e" appears in the word!
guessed: e, steps from gallows: 6, word so far: −e-e-
Guess a letter: i
* Great! The letter "i" appears in the word!
guessed: ei, steps from gallows: 6, word so far: −e-e-i-
Guess a letter: o
* Great! The letter "o" appears in the word!
guessed: eio, steps from gallows: 6, word so far: −e-e-io-
Guess a letter: u
* Great! The letter "u" appears in the word!
guessed: eiou, steps from gallows: 6, word so far: −e-e-iou-
Интервал:
Закладка: