if [ = "yes" ]
и не представляла собой верное условие. Во избежание этого следует заключить имя переменной в кавычки:
if [ "$timeofday" = "yes" ]
Теперь проверка с пустой переменной будет корректной:
if [ "" = "yes" ]
Новый сценарий будет таким:
#!/bin/sh
echo "Is it morning? Please answer yes or no "
read timeofday
if [ "$timeofday" = "yes" ]
then
echo "Good morning"
elif [ "$timeofday" = "no" ]; then
echo "Good afternoon"
else
echo "Sorry, $timeofday not recognized. Enter yes or no "
exit 1
fi
exit 0
Этот вариант безопасен, даже если пользователь в ответ на вопрос просто нажмет клавишу .
Примечание
Если вы хотите, чтобы команда echoудалила новую строку в конце, наиболее легко переносимый вариант — применить команду printf (см. разд. "printf" далее в этой главе) вместо команды echo. В некоторых командных оболочках применяется команда echo -е, но она поддерживается не всеми системами. В оболочке bash для запрета перехода на новую строку допускается команда echo -n, поэтому, если вы уверены, что вашему сценарию придется трудиться только в оболочке bash, предлагаем вам использовать следующий синтаксис:
echo -n "Is it morning? Please answer yes or no: "
Помните о том, что нужно оставлять дополнительный пробел перед закрывающими кавычками, таким образом формируется зазор перед вводимым пользователем ответом, который в этом случае выглядит четче.
for
Применяйте конструкцию forдля обработки в цикле ряда значений, которые могут представлять собой любое множество строк. Строки могут быть просто перечислены в программе или, что бывает чаще, представлять собой результат выполненной командной оболочкой подстановки имен файлов.
Синтаксис этого оператора прост:
for переменная in значения
do
операторы
done
Выполните упражнения 2.4 и 2.5.
Упражнение 2.4. Применение цикла forк фиксированным строкам
В командной оболочке значения обычно представлены в виде строк, поэтому можно написать следующий сценарий:
#!/bin/sh
for foo in bar fud 43
do
echo $foo
done
exit 0
В результате будет получен следующий вывод:
bar
fud
43
Примечание
Что произойдет, если вы измените первую строку с for foo in bar fud 43на for foo in "bar fud 43"? Напоминаем, что вставка кавычек заставляет командную оболочку считать все, что находится между ними, единой строкой. Это один из способов сохранения пробелов в переменной.
Как это работает
В данном примере создается переменная fooи ей в каждом проходе цикла forприсваиваются разные значения. Поскольку оболочка считает по умолчанию все переменные строковыми, применять строку 43 так же допустимо, как и строку fud.
Упражнение 2.5. Применение цикла forс метасимволами
Как упоминалось ранее, цикл forобычно используется в командной оболочке вместе с метасимволами или знаками подстановки для имен файлов. Это означает применение метасимвола для строковых значений и предоставление оболочке возможности подставлять все значения на этапе выполнения.
Вы уже видели этот прием в первом примере first. В сценарии применялись средства подстановки командной оболочки — символ *для подстановки имен всех файлов из текущего каталога. Каждое из этих имен по очереди используется в качестве значения переменной $fileвнутри цикла for.
Давайте бегло просмотрим еще один пример подстановки с помощью метасимвола. Допустим, что вы хотите вывести на экран все имена файлов сценариев в текущем каталоге, начинающиеся с буквы "f", и вы знаете, что имена всех ваших сценариев заканчиваются символами .sh. Это можно сделать следующим образом:
#!/bin/sh
for file in $(ls f*.sh); do
lpr $file
done
exit 0
Как это работает
В этом примере показано применение синтаксической конструкции $( команда ), которая будет подробно обсуждаться далее (в разделе, посвященном выполнению команд). Обычно список параметров для цикла forзадается выводом команды, включенной в конструкцию $().
Командная оболочка раскрывает f*.sh, подставляя имена всех файлов, соответствующих данному шаблону.
Примечание
Помните о том, что все подстановки переменных в сценариях командной оболочки делаются во время выполнения сценария, а не в процессе их написания, поэтому все синтаксические ошибки в объявлениях переменных обнаруживаются только на этапе выполнения, как было показано ранее, когда мы заключали в кавычки пустые переменные.
Читать дальше