- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Командная строка Linux - Шоттс Уильям
Шрифт:
Интервал:
Закладка:
IFS=":"
read user pw uid gid name home shell <<< "$file_info"
IFS="$OLD_IFS"
Здесь мы сохранили прежнее значение IFS, присвоили новое значение, выполнили команду read и восстановили прежнее значение IFS. Очевидно, что размещение операции присваивания перед командой позволяет получить более компактный код, действующий точно так же.
read нельзя использовать в конвейере
Даже при том, что команда read способна принимать данные со стандартного ввода, она не позволяет использовать ее следующим образом:
echo "foo" | read
Можно было бы ожидать, что этот прием сработает, но это не так. Внешне все будет выглядеть так, как будто команда успешно отработала, но при этом переменная REPLY всегда будет оставаться пустой. Почему?
Объясняется это особенностью обработки конвейеров командной оболочкой. В bash (и в других командных оболочках, таких как sh) конвейеры создают подоболочки (subshells). Они являются копиями родительской оболочки и ее окружения и используются для выполнения команд в конвейерах. В предыдущем примере команда read выполняется в подоболочке.
Для подоболочек в Unix-подобных системах создаются копии родительского окружения, которые они и используют в работе. Когда конвейер завершается, копия окружения уничтожается. Это означает, что подоболочка никогда не сможет изменить окружение родительского процесса. Как мы знаем, read присваивает значения переменным, которые становятся частью окружения. В примере выше read присвоит значение foo переменной REPLY в окружении подоболочки, но когда конвейер завершится, подоболочка и ее окружение будут уничтожены, а результат присваивания будет утрачен.
Использование встроенных строк — один из способов обойти эту проблему. Еще один способ мы увидим в главе 36.
Оператор <<< отмечает встроенную строку. Встроенная строка (here string) подобна встроенному документу, только короче, она простирается лишь до конца текущей строки кода. В данном примере строка с данными из файла /etc/passwd подается на стандартный ввод команды read. У кого-то может возникнуть вопрос, почему был выбран такой, несколько необычный, способ вместо
echo "$file_info" | IFS=":" read user pw uid gid name home shell
Скажем так: на то есть свои причины…
Проверка ввода
Использование новой для нас возможности приема ввода с клавиатуры влечет за собой дополнительную проблему: необходимость проверки введенных данных. Очень часто хорошо написанная программа отличается от плохо написанной готовностью к неожиданностям. Зачастую неожиданности возникают в форме ввода ошибочных данных. Мы уже сделали кое-что, чтобы противостоять неожиданностям в программах проверки целочисленных значений из предыдущей главы, где предусмотрено отсеивание пустых значений и значений с нецифровыми символами. Такого рода программные проверки должны выполняться для любых вводимых данных, чтобы обезопасить программу от недопустимых значений. Это особенно актуально для программ, используемых множеством пользователей. Отказ от защитных мер ради экономии простителен, только если программа пишется для однократного использования автором с целью решения некоей специальной задачи. Но даже в этом случае, если программа выполняет потенциально опасные операции, такие как удаление файлов, на всякий случай включите в нее проверку данных.
Далее приводится пример программы, проверяющий входные данные разного вида:
#!/bin/bash
# read-validate: проверка ввода
invalid_input () {
echo "Invalid input '$REPLY'" >&2
exit 1
}
read -p "Enter a single item > "
# пустой ввод (недопустимо)
[[ -z $REPLY ]] && invalid_input
# ввод множества элементов (недопустимо)
(( $(echo $REPLY | wc -w) > 1 )) && invalid_input
# введено допустимое имя файла?
if [[ $REPLY =~ ^[-[:alnum:]._]+$ ]]; then
echo "'$REPLY' is a valid filename."
if [[ -e $REPLY ]]; then
echo "And file '$REPLY' exists."
else
echo "However, file '$REPLY' does not exist."
fi
# введено вещественное число?
if [[ $REPLY =~ ^-?[[:digit:]]*.[[:digit:]]+$ ]]; then
echo "'$REPLY' is a floating point number."
else
echo "'$REPLY' is not a floating point number."
fi
# введено целое число?
if [[ $REPLY =~ ^-?[[:digit:]]+$ ]]; then
echo "'$REPLY' is an integer."
else
echo "'$REPLY' is not an integer."
fi
else
echo "The string '$REPLY' is not a valid filename."
fi
Этот сценарий предлагает пользователю ввести элемент данных и затем последовательно анализирует его содержимое. Как видите, в сценарии использовано множество идей, с которыми мы уже познакомились, включая функции [[ ]], (( )), операторы управления && и if, а также разумную дозу регулярных выражений healthy.
Меню
Часто для организации интерактивной работы используются меню. Программы, управляемые системой меню, выводят список возможных вариантов и предлагают пользователю выбрать один из них. Например, представьте программу, которая выводит следующее:
Выберите команду:
1. Вывести информацию о системе
2. Вывести информацию о дисковом пространстве
3. Вывести информацию об объеме домашнего каталога
0. Выйти
Введите номер выбранной команды [0-3] >
Используя все, что мы узнали в ходе создания программы sys_info_page, можно сконструировать программу, реализующую решение задач, перечисленных в меню, приведенном выше:
#!/bin/bash
# read-menu: программа вывода системной информации,
# управляемая с помощью меню
clear
echo "
Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
"
read -p "Enter selection [0-3] > "
if [[ $REPLY =~ ^[0-3]$ ]]; then
if [[ $REPLY == 0 ]]; then
echo "Program terminated."
exit
fi
if [[ $REPLY == 1 ]]; then
echo "Hostname: $HOSTNAME"
uptime
exit
fi
if [[ $REPLY == 2 ]]; then
df -h
exit
fi
if [[ $REPLY == 3 ]]; then
if [[ $(id -u) -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh $HOME
fi
exit
fi
else
echo "Invalid entry." >&2
exit 1
fi
Этот сценарий делится на две логические части. Первая часть выводит меню и вводит выбор пользователя. Вторая часть идентифицирует выбор и выполняет соответствующие действия. Обратите внимание, как используется команда exit в этом сценарии. Она препятствует выполнению ненужного кода после завершения затребованного действия. Наличие нескольких точек выхода из программы вообще считается дурным тоном (логику работы такой программы труднее понять), но в данном сценарии нас это устраивает.