Linux bash read примеры

Команда read (чтения) Bash

https://linuxize.com/post/bash-read/

В этом руководстве мы рассмотрим встроенную команду read.

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

read Bash

read — это встроенная команда bash, которая считывает строку из стандартного ввода (или из файлового дескриптора) и разбивает строку на слова. Первое слово присваивается первому имени, второе — второму имени и так далее.

Общий синтаксис read встроенного модуля имеет следующий вид:

Чтобы проиллюстрировать, как работает команда, откройте терминал, введите read var1 var2 и нажмите «Enter». Команда будет ждать, пока пользователь введет данные. Введите два слова и нажмите «Enter».

Слова присваиваются именам, которые передаются read команде в качестве аргументов. Используйте echo или, printf чтобы проверить это:

Вместо того, чтобы печатать на терминале, вы можете передать стандартный ввод с read помощью других методов, таких как piping, here-string или heredoc :

Вот пример использования здесь строки и printf :

Если read команде не предоставлен аргумент, REPLY переменной присваивается вся строка :

Если количество read переданных аргументов больше, чем количество слов, прочитанных из ввода, оставшиеся слова присваиваются фамилии:

В противном случае, если количество аргументов меньше количества имен, оставшимся именам присваивается пустое значение:

По умолчанию read интерпретирует обратную косую черту как escape-символ, что иногда может вызывать неожиданное поведение. Чтобы отключить экранирование обратной косой черты, вызовите команду с -r параметром.

Ниже приведен пример, показывающий, как read работает при вызове с параметром и без него -r :

Как правило, вы всегда должны использовать read с -r опцией.

Изменение разделителя

По умолчанию read строка разбивается на слова с использованием одного или нескольких пробелов, табуляции и новой строки в качестве разделителей. Чтобы использовать другой символ в качестве разделителя, назначьте его IFS переменной (Внутренний разделитель полей).

Когда IFS установлен символ, отличный от пробела или табуляции, слова разделяются ровно одним символом:

Строка разделена четырьмя словами. Второе слово — это пустое значение, представляющее отрезок между разделителями. Он создан, потому что мы использовали два символа-разделителя рядом друг с другом ( :: ).

Для разделения строки можно использовать несколько разделителей. При указании нескольких разделителей присваивайте символы IFS переменной без пробела между ними.

Ниже приведен пример использования в качестве разделителей: _ —

Строка подсказки

При написании интерактивных сценариев bash вы можете использовать read команду для получения пользовательского ввода.

Чтобы указать строку приглашения, используйте -p параметр. Приглашение печатается перед read выполнением и не включает новую строку .

Вот простой пример:

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

Приведенный ниже код предложит пользователю перезагрузить систему :

Если сценарий оболочки просит пользователей ввести конфиденциальную информацию, например пароль, используйте -s параметр, который read запрещает выводить ввод на терминал:

Назначьте слова в массив

Чтобы присвоить слова массиву вместо имен переменных, вызовите read команду с -a опцией:

Когда даны и массив, и имя переменной, все слова присваиваются массиву.

Заключение

Команда read используется для разделения строки ввода на слова.

Источник

Linux bash read примеры

Встроенная команда read является противоположностью командам echo и printf. Синтаксис команды read следующий:

Из стандартного входного потока или из дескриптора файла, указываемого в качестве аргумента в параметре -u , считывается одна строка. Первое слово из строки присваивается первому имени NAME1, второе слово — второму имени и так далее, оставшиеся слова и имеющиеся между ними разделители назначаются последнему имени NAMEN. Если слов, считываемых из входного потока меньше, чем имен, оставшимся именам присваиваются пустые значения.

Читайте также:  Adblock browser для windows

Для разбиения входной строки на слова или лексемы используются символы, хранящиеся в переменной IFS ; смотрите раздел «Разбиение на слова». Для отмены особого свойства следующего символа и для продолжения строки можно использовать символ обратного слеша.

Если имена не указываются, то считанная строка назначается переменной REPLY .

Код возврата команды read равен нулю, если не встретился символ конца файла, если не возник таймаут команды read или если дескриптор файла, указанный в качестве аргумента параметра -u , не оказался недопустимым.

Во встроенной команде read поддерживаются следующие параметры:

Таблица 8.2. Параметры встроенной команды read

Слова присваиваются подряд идущим элементам массива ANAME , присваивание начинается с элемента с индексом 0. Перед присваиванием все элементы удаляются из ANAME . Другие аргументы NAME игнорируются

В качестве завершающего элемента входной строки используется символ DELIM , а не символ новой строки.

Для чтения строки используется программа readline.

Команда read возвращает управление после чтения символов NCHARS и не ждет завершения ввода строки.

Перед попыткой прочитать какие-нибудь входные данные, сначала выдается PROMPT , который не завершается символом перевода строки. Эта строка приглашения отображается только тогда, когда входные данные поступают из терминала.

Если задан этот параметр, то обратный слеш не используется для отмены свойств специальных символов. Обратный слеш считается частью строки. В частности, пару «обратный слэш и символ новой строки» нельзя будет использовать для указания продолжения строки.

Тихий режим. Если входные данные поступают из терминала, на терминал не выдается эхо-ответ.

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

Чтение входных данных из дескиптора файла FD .

Это простой пример представляет собой улучшенный вариант скрипта leaptest.sh из предыдущей главы:

Приглашение пользователю ввести данные

В следующем примере показано, как можно использовать приглашения, объясняющие, что пользователь должен ввести.

Обратите внимание, что здесь не показаны строки, выдаваемые скриптом. Скрипт только запоминает информацию о людях, которыми интересуется Мишель, но скрипт всегда сообщит вам, что вы добавлены в список, если вас в нем не было.

Теперь другие могут запустить скрипт:

Через некоторое время список friends будет выглядеть следующим образом:

Конечно, эта ситуация не идеальна, поскольку каждый может редактировать (но не удалять) файлы Мишеля. Вы можете решить эту проблему с помощью специальных режимов доступа к файлу скрипта; смотрите описание SUID и SGID в руководстве «Введение в Linux».

Перенаправление и дескрипторы файлов

Общие положения

Как вы знаете из основных положений об использовании командной оболочки, прежде, чем команда будет выполнена, можно с помощью специальной нотации — операторов перенаправления, которые интерпретируются командной оболочкой, перенаправлять ввод и вывод команды. Перенаправлением можно пользоваться для открытия и закрытия файлов в текущей среде исполнения командной оболочки.

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

Ввод из файла и вывод в файл сопровождается обработкой целых чисел, с помощью которых отслеживаются все файлы, открываемые в данном процессе. Эти числовые значения называются дескрипторами файлов. Самыми известными являются дескрипторы файлов stdin, stdout и stderr, номера дескрипторов файлов для которых равны 0, 1 и 2, соответственно. Под этими номерами зарезервированы соответствующие им устройства. В Bash в качестве дескрипторов файлов можно также использовать порты TCP и UDP сетевых хостов.

В приведенных ниже выходных данных показывается, как зарезервированные дескрипторы файлов указывают на фактически имеющиеся устройства:

Обратите внимание, что каждый процесс имеет в /proc/self свое собственное представление, т.к. фактически это символическая ссылка на /proc/ .

Вы можете с помощью info MAKEDEV и info proc посмотреть дополнительную информацию о директории /proc и о том, что в вашей системе в каждом запущенном процессе делается с дескрипторами стандартных файлов.

Когда выполняется конкретная команда, ее выполнение состоит из следующих шагов и происходит в приведенном ниже порядке:

  • Если стандартный вывод предыдущей команды подключен через конвейер к стандартному входу текущей команды, то /proc/ /fd/0 будет заменен на тот же самый анонимный конвейер, который использовался для /proc/ /fd/1 .
  • Если стандартный вывод текущей команды подключен через конвейер к стандартному входу следующей команды, /proc/ /fd/1 будет заменен на еще один анонимный конвейер.
  • Перенаправление для текущей команды обрабатываются слева направо
  • Перенаправление «N>&M» или «N /proc/self/fd/N , так чтобы она ссылалась туда, куда и /proc/self/fd/M .
  • Перенаправление «N>файл» и «N /proc/self/fd/N , так чтобы она указывала на целевой файл.
  • Если указывается «N>&-«, то это вызывает удаление символической ссылки /proc/self/fd/N .
  • Только после этого происходит выполнение текущей команды.

Когда скрипт запускается из командной строки, то ничего меняться не будет, поскольку процесс в дочерней командной оболочке будет использовать те же самые дескрипторы файлов, что и в родительской оболочке. Когда родительская оболочка отсутствует, например, когда вы запускаете скрипт с помощью cron, дескрипторами стандартных файлов будут конвейеры или другие (временные) файлы, если не используется какой-нибудь вариант перенаправления. Это демонстрируется в приведенном ниже примере, в котором показан выход простого скрипта at:

Перенаправление ошибок

Из предыдущих примеров понятно, что вы можете для скрипта указать входной и выходной файлы (подробности смотрите в разделе «Ввод из файла и вывод в файл»), но некоторые могут забыть о перенаправлении ошибок — выход, который может позже потребоваться. К тому же, если повезет, ошибки будут отсылаться вам по почте и, возможно, удастся выявить возможные причины ошибок. Если вы не настолько удачный, ошибки могут привести к отказу в работе скрипта, а обнаружить и отослать ошибку не удастся, из-за чего вы не сможете выполнить какую-либо отладку.

Обратите внимание, что при перенаправлении ошибок важен порядок выполнения действий. Например, следующая команда, которая есть в /var/spool

будет перенаправлять стандартный выходной поток команды ls в файл unaccessible-in-spool , находящийся в /var/tmp . Команда

будет перенаправлять стандартный ввод и стандартный поток ошибок в spoollist . Команда

перенаправляет в файл только стандартный вывод, поскольку перед тем, как стандартный вывод будет перенаправлен, стандартный поток ошибок копируется в стандартный вывод.

Для удобства, ошибки, если есть уверенность в том, что они не нужны, часто перенаправляются в /dev/null . Среди скриптов запуска, имеющихся в вашей системе, можно найти сотни примеров.

Bash позволяет перенаправить в файл как стандартный вывод, так и стандартный вывод ошибок; имя файла FILE будет подставлено в следующую конструкцию:

Это эквивалентно конструкции > FILE 2>&1, которая использовалась в предыдущих примерах. Кроме того, она объединяется с перенаправлением в /dev/null , например, когда вы просто хотите выполнять команду, независимо от того, будут ошибки или нет.

Ввод из файла и вывод в файл

Использование /dev/fd

В директории /dev/fd находятся записи с именами 0 , 1 , 2 и так далее. Открытие файла /dev/fd/N эквивалентно дублированию дескриптора файла N. Если в вашей системе есть /dev/stdin , /dev/stdout и /dev/stderr , вы сможете увидеть, что они, соответственно, эквивалентны /dev/fd/0 , /dev/fd/1 и /dev/fd/2 .

Файлы директория /dev/fd используются, главным образом, из командной оболочки. Этот механизм позволяет программам, которые используют пути к файлам в качестве аргументов, обрабатывать стандартный вход и стандартный выход точно также, как и пути к другим файлам. Если в системе нет директория /dev/fd , вам потребуется искать способ обойти проблему. Это можно сделать, например, при помощи дефиса (-), указывающего, что программа должна читать из конвейера. Например:

Команда cat сначала читает файл header.txt , затем свой собственный стандартный ввод, который является выходом команды filter, и, затем, файл footer.txt. Во многих программах не учитывается особое свойство дефиса, который, когда он используется в качестве аргумента командной строки, является ссылкой на стандартный ввод или стандартный вывод. Проблемы также могут возникнуть, если дефис используется в качестве первого аргумента, т. к. он может рассматриваться как параметр предыдущей команды. Использование /dev/fd ведет к единообразию и предотвращает путаницу:

В этом примере все выходные данные дополнительно через конвейер направляются в команду lp, которая отправляет их на используемый по умолчанию принтер.

Read и exec

Назначение файлам дескрипторов

Другой взгляд на файловые дескрипторы — рассматривать их как способ назначить файлу числовое значение. Вместо того, чтобы пользоваться именем файла, вы можете пользоваться номером дескриптора файла. Для замены текущего процесса или для изменения дескриптора файла можно пользоваться встроенной командой exec. Например, ею можно пользоваться при назначении файлу дескриптора. Используйте команду

для назначения дескриптора N выходному файлу file и

для назначения дескриптора N входному файлу file . После назначения файлу дескриптора, дескриптор можно использовать с командами перенаправления так, как это показано в следующем примере:

Параметр Значение

Использование этого дескриптора файла может быть причиной проблем, смотрите главу 16 в книге «Advanced Bash-Scripting Guide» («Искусство программирования на языке сценариев командной оболочки»). Мы настоятельно рекомендуем его не использовать.

Команда read в скриптах

Ниже приведен пример, в котором показано, каким образом можно чередовать ввод данных из файла и из командной строки:

Закрытие дескрипторов файла

Поскольку дескрипторы открытых файлов наследуются в дочерних процессах, на практике важно закрывать дескриптор файла, когда он больше не нужен. Это делается следующим образом

В приведенном выше примере, дескриптор файла 7, который был назначен стандартному вводу, закрывается каждый раз, когда пользователю необходим доступ к реальному устройству стандартного ввода, как правило, к клавиатуре.

Ниже приводится простой пример перенаправления в конвейер только стандартного потока ошибок:

Встраиваемые документы (Here documents)

Часто ваш скрипт может вызывать другую программу или скрипт, в которых нужно вводит данные. С помощью встраиваемых документов (here documents) можно указать командной оболочке считывать входные данные из некоторого источника до тех пор, пока в нем не будет найдена строка, содержащая определенную подстроку (ею не могут быть завершающие пробелы). Затем все строки, считанные до этого места, будут использованы в вызванной программе или скрипте в качестве стандартного входного потока.

В результате вам не потребуется вызывать файлы по отдельности; вы можете пользоваться специальными символами командной оболочки и это будет выглядеть гораздо лучше, чем куча команд echo:

Хотя здесь мы говорим о встраиваемом документе, предполагается, что он находится внутри того же самого скрипта. Приведенный ниже пример выполняет автоматическую установку пакета даже в том случае, когда от вас требуется подтверждать установку:

И о том, как работает скрипт: когда выдается строка «Is this ok [y/N]» («Это правильно [y/N]»), скрипт автоматически отвечает «y»:

Источник

Читайте также:  Ubuntu linux kernel versions
Оцените статью
Дескриптор файла 5