Kniga-Online.club
» » » » Уильям Шоттс - Командная строка Linux. Полное руководство

Уильям Шоттс - Командная строка Linux. Полное руководство

Читать бесплатно Уильям Шоттс - Командная строка Linux. Полное руководство. Жанр: Прочая околокомпьютерная литература издательство -, год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

echo "var1 = '$var1'"

echo "var2 = '$var2'"

echo "var3 = '$var3'"

echo "var4 = '$var4'"

echo "var5 = '$var5'"

Этот сценарий вводит, присваивает переменным и выводит до пяти значений. Обратите внимание, как действует команда read, когда получает разное число значений:

[[email protected] ~]$ read-multiple

Enter one or more values > a b c d e

var1 = 'a'

var2 = 'b'

var3 = 'c'

var4 = 'd'

var5 = 'e'

[[email protected] ~]$ read-multiple

Enter one or more values > a

var1 = 'a'

var2 = ''

var3 = ''

var4 = ''

var5 = ''

[[email protected] ~]$ read-multiple

Enter one or more values > a b c d e f g

var1 = 'a'

var2 = 'b'

var3 = 'c'

var4 = 'd'

var5 = 'e f g'

Если read получит число значений меньше, чем ожидается, переменные, для которых не хватило значений, останутся пустыми, а при избыточном количестве значений на входе последняя переменная получит весь остаток введенной строки.

Если не передать переменные команде read, весь ввод будет сохранен в переменной командной оболочки REPLY:

#!/bin/bash

# read-single: чтение множества значений в переменную по умолчанию

echo -n "Enter one or more values > "

read

echo "REPLY = '$REPLY'"

Запуск этого сценария приводит к следующим результатам:

[[email protected] ~]$ read-single

Enter one or more values > a b c d

REPLY = 'a b c d'

Параметры

read поддерживает параметры, перечисленные выше в табл. 28.1.

Множество поддерживаемых параметров открывает доступ к довольно интересным способам использования read. Например, параметр -p позволяет определить строку приглашения к вводу:

#!/bin/bash

# read-single: чтение множества значений в переменную по умолчанию

read -p "Enter one or more values > "

echo "REPLY = '$REPLY'"

Параметры -t и -s позволяют писать сценарии, реализующие ввод «секретных» данных и прерывающие ввод по истечении заданного времени:

#!/bin/bash

# read-secret: ввод секретного пароля

if read -t 10 -sp "Enter secret passphrase > " secret_pass; then

echo -e "nSecret passphrase = '$secret_pass'"

else

echo -e "nInput timed out" >&2

exit 1

fi

Сценарий предлагает пользователю ввести секретный пароль и ждет 10 секунд. Если в течение этого времени ввод не был завершен, сценарий завершается с кодом ошибки. Поскольку в команду включен параметр -s, символы пароля не выводятся на экран в процессе ввода.

Выделение полей в строке ввода с помощью IFS

Обычно командная оболочка выполняет разбиение ввода на слова перед передачей его команде read. Как мы уже знаем, это означает, что слова во вводе, разделенные одним или несколькими пробелами, становятся отдельными значениями и присваиваются командой read разным переменным. Такое поведение командной оболочки регулируется переменной с именем IFS (от Internal Field Separator — внутренний разделитель полей). По умолчанию переменная IFS хранит символы пробела, табуляции и перевода строки, каждый из которых может служить разделителем полей.

Изменяя значение переменной IFS, можно управлять делением ввода на поля перед передачей команде read. Например, файл /etc/passwd хранит строки данных, в которых поля отделяются друг от друга двоеточием. Присвоив переменной IFS значение, состоящее из единственного двоеточия, можно с помощью read прочитать содержимое /etc/passwd и благополучно разделить строки на поля для присваивания разным переменным. Ниже приводится сценарий, который именно так и действует:

#!/bin/bash

# read-ifs: чтение полей из файла

FILE=/etc/passwd

read -p "Enter a username > " user_name

file_info=$(grep "^$user_name:" $FILE) (1)

if [ -n "$file_info" ]; then

IFS=":" read user pw uid gid name home shell <<< "$file_info" (2)

echo "User = '$user'"

echo "UID = '$uid'"

echo "GID = '$gid'"

echo "Full Name = '$name'"

echo "Home Dir. = '$home'"

echo "Shell = '$shell'"

else

echo "No such user '$user_name'" >&2

exit 1

fi

Этот сценарий предлагает пользователю ввести имя учетной записи в системе и затем выводит разные поля, найденные в соответствующей записи в файле /etc/passwd. В сценарии есть две интересные строки. Первая, отмеченная знаком (1), присваивает результат команды grep переменной file_info. Регулярное выражение гарантирует извлечение из файла /etc/passwd единственной строки, соответствующей введенному имени пользователя.

Вторая интересная строка, отмеченная знаком (2), состоит из трех частей: присваивания значения переменной, команды read со списком имен переменных в виде аргументов и незнакомого нам, нового оператора перенаправления. Рассмотрим сначала присваивание значения переменной.

Командная оболочка позволяет выполнять в одной строке одно или несколько операций присваивания значений переменным непосредственно перед командой, на поведение которой эти переменные влияют. Они изменяют окружение, в котором выполняется команда. Действие этих операций присваивания носит временный характер, окружение изменяется только на время выполнения команды. В данном случае в переменной IFS сохраняется символ двоеточия. То же самое можно выразить иначе:

OLD_IFS="$IFS"

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."

Перейти на страницу:

Уильям Шоттс читать все книги автора по порядку

Уильям Шоттс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


Командная строка Linux. Полное руководство отзывы

Отзывы читателей о книге Командная строка Linux. Полное руководство, автор: Уильям Шоттс. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*