Ввод и вывод Shell
Оболочка Bourne обеспечивает много способов считать и записать файлы, текст дисплея, и получить информацию от пользователя, включая echo
(описанный ранее в Основах Сценария оболочки), printf
, read
, cat
, каналы и перенаправление. В этой главе описываются эти механизмы.
Ввод и вывод Сценария оболочки Используя printf и читал
Синтаксис Оболочки Bourne обеспечивает основной ввод с очень небольшим усилием.
#!/bin/sh |
printf "What is your name? -> " |
read NAME |
echo "Hello, $NAME. Nice to meet you." |
Вы заметите две вещи об этом сценарии. Прежде всего, это представляет printf
команда. Эта команда используется потому что в отличие от этого echo
, printf
команда автоматически не добавляет новую строку до конца строки вывода. Когда необходимо использовать многократные строки кода для вывода одной строки текста, это поведение полезно. Это также просто, оказывается, удобно для подсказок.
Вторая вещь, которую Вы заметите, read
команда. Эта команда проводит строку ввода и разделяет его на серию параметров. Каждый из этих параметров присваивается переменным в read
оператор в порядке появления. Любые дополнительные поля ввода добавляются к последней записи.
Можно изменить поведение read
команда путем изменения переменной оболочки IFS
(короткий для внутренних разделителей полей). Поведение по умолчанию состоит в том, чтобы разделить вводы везде существует пространство, вкладка или новая строка. Путем замены этой можно заставить оболочку разделить поля ввода вкладками, новыми строками, точками с запятой, или даже буквой 'q'. Это изменение в поведении продемонстрировано в следующем примере:
#!/bin/sh |
printf "Type three numbers separated by 'q'. -> " |
IFS="q" |
read NUMBER1 NUMBER2 NUMBER3 |
echo "You said: $NUMBER1, $NUMBER2, $NUMBER3" |
Если, например, Вы выполняете этот сценарий и входите 1q3q57q65
, сценарий отвечает с You said: 1, 3, 57q65
. Третье значение содержит 57q65
потому что только три значения требуют в операторе чтения.
Но что, если Вы не знаете, сколько укажут параметры пользователь? Очевидно, единственный оператор чтения не может разделить ввод на произвольное число переменных, и Оболочка Bourne не содержит истинные массивы. К счастью, eval
встроенный может использоваться для моделирования массива с помощью многократных переменных оболочки. Этот метод описан в Использовании оценки, Встроенной для Структур данных, Массивов и Косвенности.
Также можно использовать for
оператор, разделяющий единственную переменную на многократные части на основе внутренних разделителей полей. Этот оператор описан в для Оператора.
Увеличьте объем I/O Используя Команду кошки
Для маленького I/O, echo
команда хорошо подходит. Однако, когда необходимо создать большие объемы данных, может быть удобно отправить многократные строки в файл одновременно. В этих целях, cat
команда может быть особенно полезной.
Отдельно, cat
команда действительно не делает ничего, что не может быть сделано с помощью операторов перенаправления (за исключением печати содержания файла на экран пользователя). Однако путем объединения его со специальным оператором <<
, можно использовать его для отправки большого количества текста к файлу (или на экран), не имея необходимость использовать echo
команда на каждой строке.
Например:
cat > mycprogram.c << EOF |
#include <stdio.h> |
int main(int argc, char *argv[]) |
{ |
char array[] = { 0x25, 115, 0 }; |
char array2[] = { 68, 0x61, 118, 0x69, 0144, 040, |
0107, 97, 0x74, 119, 0157, 0x6f, |
100, 0x20, 0x72, 117, 'l', 0x65, |
115, 041, 012, 0 }; |
printf(array, array2); |
} |
EOF |
Этот сценарий в качестве примера берет текст после строки, содержащей cat
команда до (но не включая) начинающаяся строка EOF
и хранилища это в файл mycprogram.c
. Обратите внимание на то, что маркер EOF
может быть заменен любым маркером, пока отвечают следующим условиям:
Маркер не должен содержать пробелы, если Вы не окружаете его кавычками. (Эти внешние кавычки не считают частью маркера, если Вы не заключаете им в кавычки.)
Переменные Shell от имени маркера не расширены, таким образом,
$
символ точно так же, как любой другой обычный символ.Маркер после
<<
в стартовой строке должен соответствовать маркер в начале последней строки.Маркер конца блока должен быть единственной вещью, появляющейся на строке. Если это совместно использует строку с какими-либо другими символами (включая пробел), то это будет обработано как часть текста, который будет выведен.
Маркер конца блока, который Вы выбираете, никогда не должен появляться как строка в намеченной выводимой строке.
Этот метод также часто используется для печати инструкций пользователю из интерактивного сценария оболочки. Это избегает помехи десятков строк echo
команды и делают текст намного проще считать и отредактировать в редакторе внешнего текста (при желании).
Другой классический пример этого использования cat
в действии .shar
формат файла, создаваемый инструментом shar
(короткий для Архива Оболочки). Этот инструмент берет список файлов, как введено и использует их для создания гигантского сценария оболочки, когда выполняется, воссоздающего те исходные файлы. Для предотвращения риска маркера конца блока, появляющегося во входном файле, это предварительно ожидает каждую строку со специальным символом, затем снимает изоляцию с того символа на выводе.
Каналы и перенаправление
Поскольку можно уже знать, истинная сила сценариев оболочки заключается не в самих сценариях, а в возможности считать и записать файлы и цепочечные многократные программы вместе интересными способами.
Каждая программа в основанной на UNIX или подобной UNIX системе имеет три основных дескрипторов файлов (обычно ссылка на файл или сокет) зарезервированный для основного ввода и вывода: стандартный ввод (часто сокращал stdin), стандартный вывод (stdout) и стандартная погрешность (stderr).
Первый, стандартный ввод, обычно берет ввод с клавиатуры пользователя (когда окно оболочки находится на переднем плане, конечно). Второй, стандартный вывод, обычно содержит синтезируемый текст из программы. Третья, стандартная погрешность, обычно резервируется для предупреждающих сообщений или сообщений об ошибках, которые не являются частью нормального вывода программы. Это различие между стандартным выводом и стандартной погрешностью является очень важным, как объяснено в Каналах и Перенаправлении Дескриптора файла (Оболочка Bourne).
Основное перенаправление файла
Один из наиболее распространенных типов I/O в сценариях оболочки читает и пишет файлы. К счастью, также относительно просто сделать. Чтение и запись файлов в сценариях оболочки работают точно как то, чтобы быть введенным от или отправка вывода пользователю, но со стандартным вводом, перенаправленным для прибытия из файла или со стандартным выводом, перенаправленным к файлу.
Например, следующая команда создает вызванный файл MyFile
и заливки это с одной строкой текста:
echo "a single line of text" > MyFile |
Добавление данных так же просто. Следующая команда добавляет другую строку текста к файлу MyFile
.
echo "another line of text" >> MyFile |
Необходимо заметить что оператор перенаправления (>
) создает файл, в то время как добавлять оператор (>>
) добавляет к файлу.
Многие (но не все) Совместимые с границей оболочки поддерживают третьего оператора в этой семье, объединяющегося оператора перенаправления (>&
) это перенаправляет стандартную погрешность и стандартный вывод одновременно к файлу. Например:
ls . THISISNOTAFILE >& filelistwitherrors |
Это создает вызванный файл filelistwitherrors
, содержа и распечатку текущего каталога и сообщение об ошибке о несуществовании файла THISISNOTAFILE
. Стандартный вывод и потоки стандартной погрешности объединены и выписаны к получающемуся файлу.
Каналы и перенаправление дескриптора файла (оболочка Bourne)
Самый простой пример использования каналов должен передать стандартный вывод по каналу одной программы к стандартному вводу другой программы. Введите следование командной строки:
ls -l | grep 'rwx' |
Вы будете видеть все файлы, полномочия которых (или имя) содержат буквы rwx
в порядке. ls
файлы списков команд к его стандартному выводу, и grep
команда берет свой ввод и отправляет любые строки, соответствующие определенный образец к ее стандартному выводу. Между теми двумя командами оператор канала (|
). Это говорит оболочке соединять стандартный вывод ls
к стандартному вводу grep
.
То, где различие между стандартным выводом становится значительным, когда ls
команда дает ошибку.
ls -l THISFILEDOESNOTEXIST | grep 'rwx' |
Необходимо заметить что ls
команда выпустила сообщение об ошибке (если Вам не вызвали файл THISFILEDOESNOTEXIST
в Вашем корневом каталоге, конечно). Если ls
команда отправила это сообщение об ошибке в свой стандартный вывод, это будет проглочено grep
команда, так как это не соответствует образец rwx
. Вместо этого ls
команда отправила сообщение в свой дескриптор стандартной погрешности, приведший к сообщению, идущему непосредственно в Ваш экран.
В некоторых случаях, однако, может быть полезно перенаправить сообщения об ошибках вместе с выводом. Можно сделать это при помощи специальной формы объединяющегося оператора перенаправления (>&
).
Прежде чем можно будет начать, тем не менее, необходимо знать числа дескриптора файла. Дескриптор 0 является стандартным вводом, дескриптор 1 является стандартным выводом, и дескриптор 2 является стандартной погрешностью. Таким образом следующая команда комбинирует стандартную погрешность в стандартный вывод, затем передает результат по каналу к grep:
ls -l THISFILEDOESNOTEXIST 2>&1 | grep 'rwx' |
Если Ваш сценарий должен отправить сообщение в стандартную погрешность, этот оператор также часто полезен. Следующая команда отправляет “сообщение об ошибке” в стандартную погрешность:
echo "an error message" 1>&2 |
Это работает путем взятия стандартного вывода (дескриптор 1) команды эха и перенаправляет его к стандартной погрешности (дескриптор 2).
Необходимо заметить что амперсанд (&
) кажется, ведет себя несколько по-другому, чем это сделало в Основном Перенаправлении Файла. Поскольку амперсанд сразу сопровождается числом, это заставляет вывод одного потока данных быть объединенным в другой поток. В действительности, однако, эффект является тем же (предположение, что Ваша оболочка поддерживает использование >&
отдельно).
Перенаправление (>
) оператор неявно перенаправляет стандартный вывод. Когда объединено с амперсандом и сопровождаемый именем файла, в некоторых оболочках, это объединяет стандартный вывод и стандартную погрешность и пишет результат в файл, хотя это поведение не является переносимым. Путем указания чисел сценарий является эффективно переопределяющим который дескриптор файла использовать в качестве его источника и указания дескриптора файла для получения результата вместо файла.
Каналы и перенаправление дескриптора файла (оболочка C)
Оболочка C не поддерживает полный набор перенаправления дескриптора файла, которое поддерживает Оболочка Bourne. В некоторых случаях альтернативы предоставлены. Например, можно передать по каналу стандартный вывод и стандартную погрешность к тому же процессу с помощью |&
оператор как показано в следующем отрывке:
ls -l THISFILEDOESNOTEXIST |& grep 'rwx' |
Некоторые другие операции, однако, не возможны. Вы не можете, например, перенаправить стандартную погрешность, не перенаправляя стандартный вывод. В лучшем случае если можно решить, что стандартный вывод всегда будет /dev/tty
, можно работать вокруг этого путем перенаправления стандартного вывода к /dev/tty
во-первых, затем перенаправляя и теперь пустой стандартный вывод и стандартную погрешность с помощью >&
оператор. Например, для перенаправления только стандартной погрешности к /dev/null
, Вы могли сделать это:
(ls > /dev/tty) >& /dev/null |
Этот метод не рекомендуется для общего использования, однако, поскольку это отправит вывод в Ваш экран, если кто-либо выполнит Ваш сценарий с набором стандартного вывода к файлу или каналу.
Можно также работать вокруг этого использования файла, но не интерактивным способом. Например:
(ls > /tmp/mytemporarylslisting) >& /dev/null |
cat /tmp/mytemporarylslisting |
Однако, возможно отбросить стандартный вывод и получить стандартный ввод. Например:
(ls / /bogusfile > /dev/null) |& more |
Не возможно перенаправить сообщения к стандартной погрешности с помощью оболочки C, если Вы не пишете сценарий Оболочки Bourne или программу C, чтобы сделать перенаправление для Вас.