Домой / Группы / Потоки, программные каналы и перенаправления. Перенаправление ввода и вывода

Потоки, программные каналы и перенаправления. Перенаправление ввода и вывода

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

Потоки ввода-вывода

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

  • Стандартный ввод (standard input, stdin, поток номер 0)
  • Стандартный вывод (standard output, stdout, номер 1)
  • Стандартная ошибка, или поток диагностики (standard error, stderr, номер 2)

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

Стандартный ввод

Стандартный входной поток обычно передаёт данные от пользователя к программе. Программы, которые предполагают стандартный ввод, обычно получают входные данные от устройства (например, клавиатуры). Стандартный ввод прекращается по достижении EOF (end-of-file, конец файла). EOF указывает на то, что больше данных для чтения нет.

Чтобы увидеть, как работает стандартный ввод, запустите программу cat. Название этого инструмента означает «concatenate» (связать или объединить что-либо). Обычно этот инструмент используется для объединения содержимого двух файлов. При запуске без аргументов cat открывает командную строку и принимает содержание стандартного ввода.

Теперь введите несколько цифр:

1
2
3
ctrl-d

Вводя цифру и нажимая enter, вы отправляете стандартный ввод запущенной программе cat, которая принимает эти данные. В свою очередь, программа cat отображает полученный ввод в стандартном выводе.

Пользователь может задать EOF, нажав ctrl-d, после чего программа cat остановится.

Стандартный вывод

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

echo Sent to the terminal through standard output

Команда echo без дополнительных опций отображает на экране все аргументы, переданные ей в командной строке.

Теперь запустите echo без аргументов:

Команда вернёт пустую строку.

Стандартная ошибка

Этот стандартный поток записывает ошибки, создаваемые программой, которая вышла из строя. Как и стандартный вывод, этот поток отправляет данные в терминал.

Рассмотрим пример потока ошибок команды ls. Команда ls отображает содержимое каталогов.

Без аргументов эта команда возвращает содержимое текущего каталога. Если указать в качестве аргумента ls имя каталога, команда вернёт его содержимое.

Поскольку каталога % не существует, команда вернёт стандартную ошибку:

ls: cannot access %: No such file or directory

Перенаправление потоков

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

Команды с одной угловой скобкой переписывают существующий контент целевого файла:

  • > — стандартный вывод
  • < — стандартный ввод
  • 2> — стандартная ошибка

Команды с двойными угловыми скобками не переписывают содержимое целевого файла:

  • >> — стандартный вывод
  • << — стандартный ввод
  • 2>> — стандартная ошибка

Рассмотрим следующий пример:

cat > write_to_me.txt
a
b
c
ctrl-d

В данном примере команда cat используется для записи выходных данных в файл.

Просмотрите содержимое write_to_me.txt:

cat write_to_me.txt

Команда должна вернуть:

Снова перенаправьте cat в файл write_to_me.txt и введите три цифры.

cat > write_to_me.txt
1
2
3
ctrl-d

Теперь проверьте содержимое файла.

cat write_to_me.txt

Команда должна вернуть:

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

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

cat >> write_to_me.txt
a
b
c
ctrl-d

Откройте write_to_me.txt:

1
2
3
a
b
c

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

Конвейеры

Конвейеры (pipes) перенаправляют потоки вывода одной команды на вход другой. При этом данные, передаваемые второй программе, не отображаются в терминале. На экране данные появятся только после обработки второй программой.

Конвейеры в Linux представлены вертикальной чертой.

Например:

Такая команда передаст вывод ls (содержимое текущего каталога) программе less, которая отображает передаваемые ей данные построчно. Как правило, ls выводит содержимое каталогов подряд, не разбивая на строки. Если перенаправить вывод ls в less, то последняя команда разделит вывод на строки.

Как видите, конвейер может перенаправить вывод одной команды на вход другой, в отличие от > и >>, которые перенаправляют данные только в файлы.

Фильтры

Фильтры – это команды, которые могут изменить перенаправление и вывод конвейера.

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

  • find – выполняет поиск файла по имени.
  • grep – выполняет поиск текста по заданному шаблону.
  • tee – перенаправляет стандартный ввод в стандартный вывод и один или несколько файлов.
  • tr – поиск и замена строк.
  • wc – подсчёт символов, строк и слов.

Примеры перенаправления ввода-вывода

Теперь, когда вы ознакомились с основными понятиями и механизмами перенаправления, рассмотрим несколько базовых примеров их использования.

команда > файл

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

ls ~ > root_dir_contents.txt

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

команда > /dev/null

/dev/null – это специальный файл (так называемое «пустое устройство»), который используется для подавления стандартного потока вывода или диагностики, чтобы избежать нежелательного вывода в консоль. Все данные, попадающие в /dev/null, сбрасываются. Перенаправление в /dev/null обычно используется в сценариях оболочки.

ls > /dev/null

Такая команда сбрасывает стандартный выходной поток, возвращаемый командой ls, передав его в /dev/null.

команда 2 > файл

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

mkdir "" 2> mkdir_log.txt

Эта команда перенаправит ошибку, вызванную неверным именем каталога, и запишет её в log.txt. Обратите внимание: ошибка по-прежнему отображается в терминале.

команда >> файл

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

echo Written to a new file > data.txt
echo Appended to an existing file"s contents >> data.txt

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

команда 2>>файл

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

find "" 2> stderr_log.txt
wc "" 2>> stderr_log.txt

Приведенная выше команда перенаправляет сообщение об ошибке, вызванное неверным аргументом find, в файл stderr_log.txt, а затем добавляет в него сообщение об ошибке, вызванной недействительным аргументом wc.

команда | команда

Этот шаблон перенаправляет стандартный выход первой команды на стандартный вход второй команды.

find /var lib | grep deb

Эта команда ищет в каталоге /var и его подкаталогах имена файлов и расширения deb и возвращает пути к файлам, выделяя шаблон поиска красным цветом.

команда | tee файл

Такой шаблон перенаправляет стандартный вывод команды в файл и переписывает его содержимое, а затем отображает перенаправленный выход в терминале. Если указанного файла не существует, он создает новый файл.

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

wc /etc/magic | tee magic_count.txt

Такая команда передаёт количество символов, строк и слов в файле magic (Linux использует его для определения типов файлов) команде tee, которая отправляет эти данные в терминал и в файл magic_count.txt.

команда | команда | команда >> файл

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

ls ~ | grep *tar | tr e E >> ls_log.txt

Такая команда отправляет вывод ls для каталога root команде grep. В свою очередь, grep ищет в полученных данных файлы tar. После этого результат grep передаётся команде tr, которая заменит все символы е символом Е. Полученный результат будет добавлен в файл ls_log.txt (если такого файла не существует, команда создаст его автоматически).

Заключение

Функции перенаправления ввода-вывода в Linux сначала кажутся слишком сложными. Однако работа с перенаправлением – один из важнейших навыков системного администратора.

Чтобы узнать больше о какой-либо команде, используйте:

man command | less

Например:

Такая команда вернёт полный список команд для tee.

Tags:

Перенаправление обычно осуществляется вставкой специального символа "> " между командами. Обычно синтаксис выглядит так:

Команда1 > файл1

выполняет команду1, помещая стандартный вывод в файл1.

Команда1 < файл1

выполняет команду1, используя в качестве источника ввода файл1 (вместо клавиатуры).

Команда1 < файл1 > файл2

совмещает два предыдущих варианта. Выполняет команду1 вводя из файла1 и выводя в файл2

Конвейеры

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

команда1 | команда2

Выполняет команду1 используя её поток вывода как поток ввода при выполнении команды2, что равносильно использованию двух перенаправлений и временного файла:

Команда1 > ВременныйФайл команда2 < ВременныйФайл rm ВременныйФайл

Хороший пример командных конвейеров - это объединение echo с другой командой для получения интерактивности в неинтерактивных средах, к примеру:

echo -e "ИмяПользователя\nПароль" | ftp localhost

Здесь запускается клиент, который подключается к localhost под именем ИмяПользователя, нажимает Enter и затем вводит пароль Пароль.

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

В командной оболочке UNIX, произошедшей из Bourne shell, предыдущие два действия можно усовершенствовать, указав номер(файловый дескриптор) непосредственно перед символом перенаправления. Этот номер указывает какой именно поток используется для перенаправления. В UNIX существуют следующие стандартные потоки ввода/вывода:

К примеру:

Команда1 2 > файл1

В командных оболочках произошедших от C Shell по правилам синтаксиса для указания потока, в который осуществляется перенаправление нужно добавлять символ & после символа перенаправления.

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

Find / -name .profile> results.txt 2>&1

попытается найти все файлы с именем.profile. Если выполнять эту команду без перенаправлений она будет направлять результаты поиска в , а сообщения об ошибках(к примеру о недостаточности прав доступа при попытке поиска в защищенных директориях) в . По умолчанию эти роли выполняет консоль. Если стандартный поток вывода направлен в файл результаты, то ошибки по-прежнему будут направляться в консоль. Чтобы и ошибки и результаты поиска направлялись в файл results.txt стандартные потоки ошибок и вывода были объединены используя 2>&1 .

Написание 2>&1 перед > не будет работать, так как когда интерпретатор прочитает 2>&1 , он ещё не знает куда перенаправлен стандартный поток вывода, поэтому потоки ошибок и вывода не будут объединены.

Если объединенный результат нужно направить на вход другой программы посредством конвейера, тогда последовательность 2>&1 должна стоять перед знаком конвейера. К примеру:

Find / -name .profile 2>&1 | less

Упрощенная форма записи команды:

Команда> файл 2>&1

выглядит так:

Команда &> файл

Команда>& файл

Цепочка конвейеров

Команды перенаправления и конвейеризации могут быть объединены в цепочки для получения более сложных команд, к примеру:

Ls | grep ".sh" | sort> shlist

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

Перенаправление в несколько выводов

Стандартная команда может перенаправить вывод команды в несколько мест одновременно. Пример:

Ls -lrt | tee файл1

направляет стандартный вывод команды ls -lrt (список файлов) как в консоль так и в файл1 .

Перенаправление с добавлением

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

Команда1>> файл1

Встроенный документ

Некоторые оболочки, и даже прикладные ЯВУ (PHP], Perl) допускают синтаксис встроенных документов (см. Heredoc-синтаксис), позволяющий направлять входной поток из самого файла программы, например: cat« EOF Здесь помещается произвольный текст, в том числе включающий в себя специальные символы EOF

Завершающая сигнатура окончания встроенного документа EOF (можно использовать произвольное значение, но часто используется именно EOF - соответственно смыслу) должна начинаться с начала строки.

Любая программа - это "автомат", предназначенный для обработки данных: получая на входе одну информацию, она в результате работы выдает другую. Хотя входящая и/или выходящая информация может быть и нулевой, т. е. попросту отсутствовать. Те данные, которые передаются программе для обработки - это ее ввод, то, что она выдает в результате работы - вывод. Организация ввода и вывода для каждой программы - это задача операционной системы.

Каждая программа работает с данными определенного типа: текстовыми, графическими, звуковыми и т. п. Как, наверное, уже стало понятно, основной интерфейс управления системой в Linux - это терминал, который предназначен для передачи текстовой информации от пользователя системе и обратно. Поскольку ввести с терминала и вывести на терминал можно только текстовую информацию, то ввод и вывод программ, связанных с терминалом, тоже должен быть текстовым. Однако необходимость оперировать с текстовыми данными не ограничивает возможности управления системой, а, наоборот, расширяет их. Человек может прочитать вывод любой программы и разобраться, что происходит в системе, а разные программы оказываются совместимыми между собой, поскольку используют один и тот же вид представления данных - текстовый.

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

Рассмотрим сначала пару команд, с помощью которых можно организовать ввод/вывод.

Команды вывода на стандартное устройство вывода

Linux предоставляет несколько команд для вывода сообщений в стандартный поток вывода:

  • echo - Вывести строку в стандартный поток вывода.
  • printf - Вывести форматированный текст в стандартный поток вывода.
  • yes - Выводить повторяющийся текст в стандартный поток вывода.
  • seq - Вывести последовательность чисел в стандартный поток вывода
  • clear Очистить экран или окно.

Например, при использовании команды echo если указать управляющий символ \с, то по завершении вывода не будет осуществлен переход в новую строку:

$ echo "Как вас зовут?\c"

Как вас зовут?$

Здесь $ – символ приглашения.

В строке также можно вычислять значения переменных интерпретатора shell и даже других команд. Например, следующая команда сообщает о том, каков начальный каталог текущего пользователя (переменная среды $HOME) и к какому терминалу он подключен (команда tty заключена в обратные кавычки, чтобы интерпретатор поместил в строку результат ее выполнения).

$ echo "Ваш начальный каталог - $HOME, вы подключены к терминалу - `tty` "

Ваш начальный каталог - /home/knoppix, вы подключены к терминалу - /dev/tty1

Так как двойные кавычки в интерпретаторе shell имеют специальное назначение, то для того чтобы в выводимую строку включить двойные кавычки нужно отменить их специальное назначение с помощью обратной косой черты (\). Так отменяется назначение любого специального символа.

Например, чтобы вывести строку “/dev/tty1” необходимо выполнить:

$echo “\”/dev/tty1\””

Команды ввода из стандартного устройства ввода

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

Следующий сценарий вызывает отдельную команду read для чтения каждой переменной.


$ cat test
#!/bin/bash
echo “Имя: \с”
read name
echo “Фамилия: \c”
read surname
echo “Имя=” $name “Фамилия=” $surname

Тогда для выполнения этого сценария необходимо файлу test дать право выполнения: chmod 0755 test и запустить его./test. Результат выполнения: Имя: Иван Фамилия: Петров Имя=Иван Фамилия=Петров

СТАНДАРТНЫЕ ПОТОКИ ВВОДА, ВЫВОДА И ОШИБОК

Каждая запущенная из командного интерпретатора программа получает три открытых потока ввода/вывода:

Стандартный ввод (sldin) - стандартный вывод(sldout) - стандартный вывод ошибок (stderr)

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

При этом с каждым процессом (командой, сценарием и т.п.), выполняемым в интерпретаторе shell, связан рад открытых файлов, из которых процесс может читать свои данные: и в которые он может записывать их. Каждый из этих файлов идентифицируется числом, называемым дескриптором файла, но первые три файла являются потоками ввода/вывода по умолчанию:

Файл Дескриптор
Стандартный поток ввода 0
Стандартный поток вывода 1
Стандартный поток ошибок 2

В действительности создается 12 открытых файлов, но файлы с дескрипторами 0, 1 и 2 резервируются для стандартных потоков ввода, вывода и ошибок. Пользователи могут также работать с файлами, имеющими дескрипторы от 3 до 9 (зарезервированы).

Файл стандартного потока ввода (sldin) имеет дескриптор 0. Из этого файла процессы извлекают свои входные данные. По умолчанию входной поток ассоциирован с клавиатурой (устройство /dev/tty), но чаше всего он поступает по каналу от других процессов или из обычного файла.

Файл стандартного потока вывода (stdout) имеет дескриптор 1. В этот файл записываются все выходные данные процесса. По умолчанию данные выводятся на экран терминала (устройство/dev/tty), но их можно также перенаправить в файл или послать по каналу другому процессу.

Файл стандартного потока ошибок (siderr) имеет дескриптор 2. В этот файл записываются сообщения об ошибках, возникающих в ходе выполнения команды. По умолчанию сообщения об ошибках выводятся на экран терминала (устройство /dev/tty), но их также можно перенаправить в файл. Зачем же для регистрации ошибок выделять специальный файл? Дело в том, что это очень удобный способ выделения из результатов работы команды собственно выходных данных, а также хорошая возможность эффективно организовать ведение различного рода журнальных файлов.

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

Т.е. при вызове команд можно указывать, откуда следует принимать входные данные и куда необходимо направлять выходные данные, а также сообщения об ошибках. По умолчанию, если не указано иное, подразумевается работа с терминалом: данные вводятся с клавиатуры и выводятся на экран. Но интерпретатор shell располагает механизмом переадресации, позволяющим ассоциировать стандартные потоки с различными файлами. При этом во время перенаправления стандартного потока ошибок следует указывать дескриптор файла (2). Для потоков ввода и вывода делать это не обязательно.

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

% cat myfile - создаст в текущей директории пустой файл myfile.

/dev/null - специальный файл, представляющий собой т. н. «пустое устройство». Запись в него происходит успешно, независимо от объёма «записанной» информации. Чтение из /dev/null эквивалентно считыванию конца файла EOF.

Перенаправление потоков ввода-вывода осуществляется, подобно DOS (Точнее, синтаксис перенаправления потоков ОС DOS восприняла от UNIX) с помощью символов:

> - перенаправление стандартного потока вывода
>> - перенаправление стандартного потока вывода в режиме дозаписи
< - перенаправление стандартного потока ввода
<< - получение данные из стандартного потока ввода до тех пор, пока не встретится разделитель

Однако, в отличие от DOS при создании программного канала между двумя процессами ОС UNIX/Linux запускает оба процесса одновременно и осуществляет передачу информации через системный буфер (без промежуточной записи на жесткий диск). Таким образом, программные каналы в ОС UNIX/Linux являются весьма эффективным способом обмена. В случае переполнения системного буфера (например если ``передающая"" программа выдает информацию в канал быстрее чем ее может обработать ``принимающая"" программа) ОС автоматически приостанавливает тот процесс, который осуществляет запись в канал до освобождения буфера.

Наиболее распространенные операторы переадресации

№п/п Синтаксис Описание
1 команда > файл Направляет стандартный поток вывода в новый файл

2 команда 1> файл Направляет стандартный поток вывода в указанный файл

3 команда >> файл Направляет стандартный поток вывода в указанный файл (режим присоединения)

4 команда > файл 2>&1 Направляет стандартные потоки вывода и ошибок в указанный файл

5 команда 2> файл Направляет стандартный поток ошибок в указанный файл

6 команда 2>> файл Направляет стандартный поток ошибок в указанный файл (режим присоединения)

7 команда >> файл 2>&1 Направляет стандартные потоки вывода и ошибок в указанный файл (режим присоединения)

8 команда < файл1 > файл2 Получает входные данные из первого файла и направляет выходные данные во второй файл

9 команда < файл в качестве стандартного входного потока получает данные из указанного файла

10 команда << разделитель Получает данные из стандартного потока ввода до тех пор, пока не встретится разделитель

11 команда <&m В качестве стандартного входного потока получает дан­ные из файла с дескриптором m

12 команда >&m Направляет стандартный поток вывода в файл с дескриптором m

Оператор n>&m позволяет перенаправить файл с дескриптором n туда, куда направлен файл с дескриптором m. Подобных операторов в командной строке может быть несколько, в этом случае они вычисляются слева направо.

Команда exec и применение дескрипторов файлов

Команда exec заменяет текущий интерпретатор shell указанной командой. Обычно она используется для того, чтобы закрыть текущий интерпретатор и запустить другой. Но у нее есть и другое применение.

Например, команда вида

Exec < файл делает указанный файл стандартным входным потоком всех команд. Выполнять ее в
интерактивном режиме нет смысла - она предназначена для использования в сценариях,
чтобы все идущие после нее команды читали свои входные данные из файла. В этом случае
в конце сценария обязательно должна стоять команда

Exec <&– которая закрывает стандартный входной поток (в данном случае файл). Подобный прием применяется
преимущественно в сценариях, выполняющихся при выходе из системы.

Команда exec указатель на файл с дескриптором 0 (stdin). Восстановить этот указатель можно будет только по завершении работы сценария.
Если же в сценарии предполагается продолжить чтение данных с клавиатуры, то необходимо сохранить
указатель на прежний входной поток. Ниже приведен небольшой сценарий, в котором демонстрируется, как это сделать.

$ cat f_desc
#!/bin/bash
exec 3<&0 0<file
read linel
read line2
exec 0<&3
echo $1inel
echo $line2

Первая команда exec сохраняет указатель на стандартный входной поток (stdin) в файле с дескриптором 3
(допускается любое целое число в диапазоне от 3 до 9), а затем открывает файл file для чтения. Следующие две команды read
читают из файла две строки текста. Вторая команда exec восстанавливает указатель на стандартный входной поток: теперь
он связан с файлом stdin, а не file. Завершающие команды echo отображают на экране содержимое прочитанных строк,
которые были сохранены в переменных linel и Iine2.

Результат работы сценария:
$ ./ f_desc
Привет!
Пока!

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

В следующей таблице описаны операторы перенаправления потоков ввода и вывода команд.

Оператор перенаправления Описание
> Записывает данные на выходе команды вместо командной строки в файл или на устройство, например, на принтер.
< Читает поток входных данных команды из файла, а не с клавиатуры.
>> Добавляет выходные данные команды в конец файла, не удаляя при этом существующей информации из файла.
>& Считывает данные на выходе одного дескриптора как входные данные для другого дескриптора.
<& Считывает входные данные одного дескриптора как выходные данные другого дескриптора.
| Считывает выходные данные одной команды и записывает их на вход другой команды. Эта процедура известна под названием «канал».

По умолчанию, входные данные команды (дескриптор STDIN) отсылаются с клавиатуры интерпретатору команд Cmd.exe, далее Cmd.exe отправляет выходные данные команды (дескриптор STDOUT) в окно командной строки.

В следующей таблице представлены доступные дескрипторы.

Номера от 0 до 9 представляют первые 10 дескрипторов. Для запуска программы и перенаправления любого из 10 дескрипторов используется интерпретатор команд Cmd.exe. Для задания требуемого дескриптора перед оператором перенаправления введите его номер. Если дескриптор не определен, то по умолчанию оператором перенаправления ввода «<» будет ноль (0), а оператором перенаправления вывода «>» будет единица (1). После ввода оператора «<» или «>» необходимо указать, откуда читать и куда записывать данные. Можно задать имя файла или любой из существующих дескрипторов.

Для задания перенаправления в существующие дескрипторы используется амперсанд (&), затем номер требуемого дескриптора (например, & номер_дескриптора ). Например, для перенаправления дескриптора 2 (STDERR) в дескриптор 1 (STDOUT) введите:

Дублирование дескрипторов

Оператор перенаправления «&» дублирует выходные или входные данные с одного заданного дескриптора на другой заданный дескриптор. Например, для отправки выводных данных команды dir в файл File.txt и отправки ошибки вывода в файл File.txt введите:

dir>c:\file.txt 2>&1

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

Перенаправление ввода команд (<)

Для перенаправления ввода команд с цифровой клавиатуры на файл или на устройство используйте оператор «<». Например, для ввода команды sort из файла List.txt введите:

sort

Содержимое файла File.txt появится в командной строке в виде списка в алфавитном порядке.

Оператор «<» открывает заданное имя файла с доступом только для чтения. Поэтому с его помощью нельзя записывать в файл. Например, при запуске программы с оператором <&2 все попытки прочитать дескриптор 0 ни к чему не приведут, так как изначально он был открыт с доступом только для записи.

Примечание

  • Дескриптор 0 задан по умолчанию для оператора перенаправления ввода «<».

Перенаправление вывода команд (>)

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

Для перенаправления вывода команд из окна командной строки в файл или на устройство применяется оператор «>». Этот оператор используется с большинством команд. Например, для перенаправления вывода команды dir в файл Dirlist.txt введите:

dir>dirlist.txt

Если файл Dirlist.txt не существует, интерпретатор команд Cmd.exe создаст его. Если файл существует, Cmd.exe заменит информацию в файле на данные, полученные от команды dir .

Для запуска команды netsh routing dump и последующей отправки результатов ее работы в Route.cfg введите:

netsh routing dump > c:\route.cfg

Оператор «>» открывает заданный файл с доступом только для записи. Поэтому с помощью данного оператора файл прочитать нельзя. Например, при запуске программы с оператором перенаправления <&0 все попытки записать дескриптор 1 ни к чему не приведут, так как изначально дескриптор 0 был открыт с доступом только для чтения.

Примечание.

  • Дескриптор 1 задан по умолчанию для оператора перенаправления вывода «>».

Использование оператора «<&» для перенаправления ввода и дублирования

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

Например, для считывания файла File.txt на вход в дескриптор 0 (STDIN) введите:

Для открытия файла File.txt, сортировки его содержимого и последующей отправки в окно командной строки (STDOUT) введите:

sort< file.txt

Для того чтобы найти файл File.txt и перенаправить дескриптор 1 (STDOUT) и дескриптор 2 (STDERR) в Search.txt введите:

findfile file.txt>search.txt 2<&1

Для дублирования определенного пользователем дескриптора 3 в качестве входной информации для дескриптора 0 (STDIN) введите:

Использование оператора «>&» для перенаправления ввода и дублирования

При перенаправлении вывода в файл и задании существующего имени файла интерпретатор команд Cmd.exe открывает файл с доступом только для записи и переписывает его содержимое. Если дескриптор задан, интерпретатор команд Cmd.exe дублирует файл в существующий дескриптор.

Для дублирования определенного пользователем дескриптора 3 в дескриптор 1 введите:


Для перенаправления всех выходных данных, включая выходные данные дескриптора 2 (STDERR), команды ipconfig в дескриптор 1 (STDOUT) и последующего перенаправления выходных данных в Output.log введите:


ipconfig.exe>>output.log 2>&1

Использование оператора «>>» для добавления вывода

Для добавления выходных данных команды в конец файла без потери хранящейся в нем информации используется двойной символ «больше» (>>). Например, следующая команда добавляет список каталогов, созданный командой dir , в файл Dirlist.txt:


dir>>dirlist.txt

Для добавления выходных данных команды netstat в конец файла Tcpinfo.txt введите:


netstat>>tcpinfo.txt

Иногда удобнее записывать это следующим образом:

SET OutFile="%~n0.html" > %OutFile% ECHO ^ >> %OutFile% ECHO ^ >> %OutFile% ECHO ^best page^ >> %OutFile% ECHO ^ >> %OutFile% ECHO ^ >> %OutFile% ECHO Hello World >> %OutFile% ECHO ^ >> %OutFile% ECHO ^

Использование оператора канала (|)

Оператор канала «вертикальная линия» (|) забирает выходные данные одной команды (по умолчанию STDOUT) и направляет их на вход другой команды (по умолчанию STDIN). Например, следующая команда сортирует каталог:

В данном примере обе команды запускаются одновременно, но команда sort приостанавливает работу до получения выходных данных команды dir . Команда sort использует выходные данные команды dir в качестве своих входных данных, а затем свои выходные данные отправляет в дескриптор 1 (STDOUT).

Комбинирование команд с операторами перенаправления

Комбинируя команды-фильтры с другими командами и именами файлов, можно создавать команды на заказ. Например, для сохранения имен файлов, содержащих строку «LOG», используется следующая команда:

dir /b | find "LOG" > loglist.txt

Выход команды dir отсылается в команду-фильтр find . Имена файлов, содержащие строку «LOG», хранятся в файле Loglist.txt в виде списка (например, NetshConfig.log, Logdat.svd и Mylog.bat).

При использовании более одного фильтра в одной команде их необходимо отделять с помощью канала (|). Например, следующая команда ищет в каждом каталоге диска C файлы, в названии которых присутствует строка «Log», и выводит их постранично на экран:

dir c:\ /s /b | find "LOG" | more

Наличие канала (|) указывает cmd.exe , что выход команды DIR нужно отправить команде-фильтру find . Команда find выбирает только те имена файлов, в которых содержится строка «LOG». Команда more выводит на экран имена файлов, полученные командой find с паузой после заполнения каждого экрана. Дополнительные сведения о командах-фильтрах смотри в разделе

В системе по-умолчанию всегда открыты три "файла" — (клавиатура), (экран) и (вывод сообщений об ошибках на экран). Эти, и любые другие открытые файлы, могут быть перенапрвлены. В данном случае, термин "перенаправление" означает получить вывод из файла, команды, программы, сценария или даже отдельного блока в сценарии (см. Пример 3-1 и Пример 3-2) и передать его на вход в другой файл, команду, программу или сценарий.

С каждым открытым файлом связан дескриптор файла. Дескрипторы файлов, и — 0, 1 и 2, соответственно. При открытии дополнительных файлов, дескрипторы с 3 по 9 остаются незанятыми. Иногда дополнительные дескрипторы могут сослужить неплохую службу, временно сохраняя в себе ссылку на, или. Это упрощает возврат дескрипторов в нормальное состояние после сложных манипуляций с перенаправлением и перестановками (см. Пример 16-1).

COMMAND_OUTPUT > # Перенаправление stdout (вывода) в файл. # Если файл отсутствовал, то он создется, иначе — перезаписывается. ls -lR > dir-tree.list # Создает файл, содержащий список дерева каталогов. : > filename # Операция > усекает файл "filename" до нулевой длины. # Если до выполнения операции файла не существовало, # то создается новый файл с нулевой длиной (тот же эффект дает команда "touch"). # Символ: выступает здесь в роли местозаполнителя, не выводя ничего. > filename # Операция > усекает файл "filename" до нулевой длины. # Если до выполнения операции файла не существовало, # то создается новый файл с нулевой длиной (тот же эффект дает команда "touch"). # (тот же результат, что и выше — ": >", но этот вариант неработоспособен # в некоторых командных оболочках.) COMMAND_OUTPUT >> # Перенаправление stdout (вывода) в файл. # Создает новый файл, если он отсутствовал, иначе — дописывает в конец файла. # Однострочные команды перенаправления # (затрагивают только ту строку, в которой они встречаются): # ——————————————————————— 1>filename # Перенаправление вывода (stdout) в файл "filename". 1>>filename # Перенаправление вывода (stdout) в файл "filename", файл открывается в режиме добавления. 2>filename # Перенаправление stderr в файл "filename". 2>>filename # Перенаправление stderr в файл "filename", файл открывается в режиме добавления. &>filename # Перенаправление stdout и stderr в файл "filename". #============================================================================== # Перенаправление stdout, только для одной строки. LOGFILE=script.log echo "Эта строка будет записана в файл \"$LOGFILE\"." 1>$LOGFILE echo "Эта строка будет добавлена в конец файла \"$LOGFILE\"." 1>>$LOGFILE echo "Эта строка тоже будет добавлена в конец файла \"$LOGFILE\"." 1>>$LOGFILE echo "Эта строка будет выведена на экран и не попадет в файл \"$LOGFILE\"." # После каждой строки, сделанное перенаправление автоматически "сбрасывается". # Перенаправление stderr, только для одной строки. ERRORFILE=script.errors bad_command1 2>$ERRORFILE # Сообщение об ошибке запишется в $ERRORFILE. bad_command2 2>>$ERRORFILE # Сообщение об ошибке добавится в конец $ERRORFILE. bad_command3 # Сообщение об ошибке будет выведено на stderr, #+ и не попадет в $ERRORFILE. # После каждой строки, сделанное перенаправление также автоматически "сбрасывается". #============================================================================== 2>&1 # Перенаправляется stderr на stdout. # Сообщения об ошибках передаются туда же, куда и стандартный вывод. i> i в j . # Вывод в файл с дескриптором i передается в файл с дескриптором j . >&j # Перенаправляется файл с дескриптором 1 (stdout) в файл с дескриптором j . # Вывод на stdout передается в файл с дескриптором j . 0< FILENAME < FILENAME # Ввод из файла. # Парная команде ">", часто встречается в комбинации с ней. # # grep search-word filename # Файл "filename" открывается на чтение и запись, и связывается с дескриптором "j". # Если "filename" отсутствует, то он создается. # Если дескриптор "j" не указан, то, по-умолчанию, бередся дескриптор 0, stdin. # # Как одно из применений этого — запись в конкретную позицию в файле. echo 1234567890 > File # Записать строку в файл "File". exec 3<> File # Открыть "File" и связать с дескриптором 3. read -n 4 <&3 # Прочитать 4 символа. echo -n . >&3 # Записать символ точки. exec 3>&- # Закрыть дескриптор 3. cat File # ==> 1234.67890 # Произвольный доступ, да и только! | # Конвейер (канал). # Универсальное средство для объединения команд в одну цепочку. # Похоже на ">", но на самом деле — более обширная. # Используется для объединения команд, сценариев, файлов и программ в одну цепочку (конвейер). cat *.txt | sort | uniq > result-file # Содержимое всех файлов.txt сортируется, удаляются повторяющиеся строки, # результат сохраняется в файле "result-file".

Операции перенаправления и/или конвейеры могут комбинироваться в одной командной строке.

command < input-file > output-file command1 | command2 | command3 > output-file См. Пример 12-23 и Пример A-17.

Допускается перенаправление нескольких потоков в один файл.

ls -yz >> command.log 2>&1 # Сообщение о неверной опции "yz" в команде "ls" будет записано в файл "command.log". # Поскольку stderr перенаправлен в файл.

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

Закрыть дескриптор входного файла.

0<&-, <&-

Закрыть дескриптор выходного файла.

1>&-, >&-

Дочерние процессы наследуют дескрипторы открытых файлов. По этой причине и работают конвейеры. Чтобы предотвратить наследование дескрипторов — закройте их перед запуском дочернего процесса.

# В конвейер передается только stderr. exec 3>&1 # Сохранить текущее "состояние" stdout. ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Закрыть дескр. 3 для "grep" (но не для "ls"). # ^^^^ ^^^^ exec 3>&- # Теперь закрыть его для оставшейся части сценария. # Спасибо S.C.

Дополнительные сведения о перенаправлении ввода/вывода вы найдете в Приложение D.

16.1. С помощью команды exec

Команда exec перенаправляет ввод со на файл. С этого момента весь ввод, вместо (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.

Пример 16-1. Перенаправление с помощью exec

#!/bin/bash # Перенаправление stdin с помощью "exec". exec 6<&0 # Связать дескр. #6 со стандартным вводом (stdin). # Сохраняя stdin. exec < data-file # stdin заменяется файлом "data-file" read a1 # Читается первая строка из "data-file". read a2 # Читается вторая строка из "data-file." echo echo "Следующие строки были прочитаны из файла." echo "——————————————" echo $a1 echo $a2 echo; echo; echo exec 0<&6 6<&- # Восстанавливается stdin из дескр. #6, где он был предварительно сохранен, #+ и дескр. #6 закрывается (6<&-) освобождая его для других процессов. # # <&6 6<&- дает тот же результат. echo -n "Введите строку " read b1 # Теперь функция "read", как и следовало ожидать, принимает данные с обычного stdin. echo "Строка, принятая со stdin." echo "—————————" echo "b1 = $b1" echo exit 0

Аналогично, конструкция exec >filename перенаправляет вывод на в заданный файл. После этого, весь вывод от команд, который обычно направляется на, теперь выводится в этот файл.

Пример 16-2. Перенаправление с помощью exec

#!/bin/bash # reassign-stdout.sh LOGFILE=logfile.txt exec 6>&1 # Связать дескр. #6 со stdout. # Сохраняя stdout. exec > $LOGFILE # stdout замещается файлом "logfile.txt". # ———————————————————— # # Весь вывод от команд, в данном блоке, записывается в файл $LOGFILE. echo -n "Logfile: " date echo "————————————-" echo echo "Вывод команды \"ls -al\"" echo ls -al echo; echo echo "Вывод команды \"df\"" echo df # ———————————————————— # exec 1>&6 6>&- # Восстановить stdout и закрыть дескр. #6. echo echo "== stdout восстановлено в значение по-умолчанию == " echo ls -al echo exit 0

Пример 16-3. Одновременное перенаправление устройств, и, с помощью команды exec

#!/bin/bash # upperconv.sh # Преобразование символов во входном файле в верхний регистр. E_FILE_ACCESS=70 E_WRONG_ARGS=71 if [ ! -r "$1" ] # Файл доступен для чтения? then echo "Невозможно прочитать из заданного файла!" echo "Порядок использования: $0 input-file output-file" exit $E_FILE_ACCESS fi # В случае, если входной файл ($1) не задан #+ код завершения будет этим же. if [ -z "$2" ] then echo "Необходимо задать выходной файл." echo "Порядок использования: $0 input-file output-file" exit $E_WRONG_ARGS fi exec 4<&0 exec < $1 # Назначить ввод из входного файла. exec 7>&1 exec > $2 # Назначить вывод в выходной файл. # Предполагается, что выходной файл доступен для записи # (добавить проверку?). # ———————————————— cat — | tr a-z A-Z # Перевод в верхний регистр # ^^^^^ # Чтение со stdin. # ^^^^^^^^^^ # Запись в stdout. # Однако, и stdin и stdout были перенаправлены. # ———————————————— exec 1>&7 7>&- # Восстановить stdout. exec 0<&4 4<&- # Восстановить stdin. # После восстановления, следующая строка выводится на stdout, чего и следовало ожидать. echo "Символы из \"$1\" преобразованы в верхний регистр, результат записан в \"$2\"." exit 0

Next: Перенаправление ошибок в файл Up: Перенаправление ввода-вывода Previous: Перенаправление ввода из файла Contents Index

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

Для перенаправления стандартного вывода в файл используйте оператор `>’.

Перенаправление ввода/вывода в Linux

Укажите после имени команды оператор >, а затем имя файла, который будет служить приемником вывода. Например, чтобы записать вывод результатов работы программы в файл, введите:

Если Вы перенаправите стандартный вывод в уже существующий файл, он будет перезаписан с начала. Чтобы добавить стандартный вывод к содержимому существующего файла, необходимо использовать оператор `»’. Например, для добавления результатов работы при повторном запуске программы в файл, введите:

Alex Otwagin 2002-12-16

Программа обычно ценна тем, что может обрабатывать данные: принимать одно, на выходе выдавать другое, причём в качестве данных может выступать практически что угодно: текст, числа, звук, видео… Потоки входных и выходных данных для команды называются ввод и вывод . Потоков ввода и вывода у каждой программы может быть и по несколько. В каждый процесс, при создании в обязательном порядке получает так называемые стандартный ввод (standard input, stdin) и стандартный вывод (standard output, stdout) и стандартный вывод ошибок (standard error, stderr).

Стандартные потоки ввода/вывода предназначены в первую очередь для обмена текстовой информацией. Тут даже не важно, кто общается с помощью текстов: человек с программой или программы междй собой - главное, чтобы у них был канал передачи данных и чтобы они говорили «на одном языке».

Текстовый принцип работы с машиной позволяет отвлечься от конкретных частей компьютера, вроде системной клавиатуры и видеокарты с монитором, рассматривая единое оконечное устройство , посредством которого пользователь вводит текст (команды) и передаёт его системе, а система выводит необходимые пользователю данные и сообщения (диагностику и ошибки). Такое устройство называется терминалом . В общем случае терминал - это точка входа пользователя в систему, обладающая способностью передавать текстовую информацию. Терминалом может быть отдельное внешнее устройство, подключаемое к компьютеру через порт последовательной передачи данных (в персональном компьютере он называется «COM port»). В роли терминала может работать (с некоторой поддержкой со стороны системы) и программа (например, xterm или ssh). Наконец, виртуальные консоли - тоже терминалы, только организованные программно с помощью подходящих устройств современного компьютера.

При работе с командной строкой, стандартный ввод командной оболочки связан с клавиатурой, а стандартный вывод и вывод ошибок - с экраном монитора (или окном эмулятора терминала). Покажем на примере простейшей команды - cat. Обычно команда cat читает данные из всех файлов, которые указаны в качестве её параметров, и посылает считанное непосредственно в стандартный вывод (stdout). Следовательно, команда

/home/larry/papers# cat history-final masters-thesis

выведет на экран сначала содержимое файла, а затем - файла.

Однако если имя файла не указано, программа cat читает входные данные из stdin и немедленно возвращает их в stdout (никак не изменяя). Данные проходят через cat , как через трубу. Приведём пример:

/home/larry/papers# cat Hello there. Hello there. Bye. Bye. Ctrl D /home/larry/papers#

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

Приведём другой пример. Команда sort читает строки вводимого текста (также из stdin, если не указано ни одного имени файла) и выдаёт набор этих строк в упорядоченном виде на stdout. Проверим её действие.

/home/larry/papers# sort bananas carrots apples Ctrl+D apples bananas carrots /home/larry/papers#

Как видно, после нажатия Ctrl D , sort вывела строки упорядоченными в алфавитном порядке.

Стандартный ввод и стандартный вывод

Допустим, вы хотите направить вывод команды sort в некоторый файл, чтобы сохранить упорядоченный по алфавиту список на диске. Командная оболочка позволяет перенаправить стандартный вывод команды в файл, используя символ. Приведём пример:

/home/larry/papers# sort > shopping-list bananas carrots apples Ctrl D /home/larry/papers#

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

/home/larry/papers# cat shopping-list apples bananas carrots /home/larry/papers#

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

/home/larry/papers# sort items shopping-list /home/larry/papers# cat shopping-list apples bananas carrots /home/larry/papers#

Однако можно поступить иначе, перенаправив не только стандартный вывод, но и стандартный ввод утилиты из файла, используя для этого символ:

/home/larry/papers# sort < items apples bananas carrots /home/larry/papers#

Результат команды sort < items эквивалентен команде sort items , однако первая из них демонстрирует следующее: при выдаче команды sort < items система ведёт себя так, как если бы данные, которые содержатся в файле, были введены со стандартного ввода. Перенаправление осуществляется командной оболочкой. Команде sort не сообщалось имя файла: эта команда читала данные из своего стандартного ввода, как если бы мы вводили их с клавиатуры.

Введём понятие фильтра . Фильтром является программа, которая читает данные из стандартного ввода, некоторым образом их обрабатывает и результат направляет на стандартный вывод. Когда применяется перенаправление, в качестве стандартного ввода и вывода могут выступать файлы. Как указывалось выше, по умолчанию, stdin и stdout относятся к клавиатуре и к экрану соответственно. Программа sort является простым фильтром - она сортирует входные данные и посылает результат на стандартный вывод. Совсем простым фильтром является программа cat - она ничего не делает с входными данными, а просто пересылает их на выход.

Выше уже демонстрировалось, как использовать программу sort в качестве фильтра. В этих примерах предполагалось, что исходные данные находятся в некотором файле или что эти исходные данные будут введены с клавиатуры (стандартного ввода). Однако как поступить, если вы хотите отсортировать данные, которые являются результатом работы какой-либо другой команды, например, ls ?

Будем сортировать данные в обратном алфавитном порядке; это делается опцией команды sort . Если вы хотите перечислить файлы в текущем каталоге в обратном алфавитном порядке, один из способов сделать это будет таким.

Перенаправление ввода-вывода

Применим сначала команду ls :

/home/larry/papers# ls english-list history-final masters-thesis notes /home/larry/papers#

Теперь перенаправляем выход команды ls в файл с именем file-list

/home/larry/papers# ls > file-list /home/larry/papers# sort -r file-list notes masters-thesis history-final english-list /home/larry/papers#

Здесь выход команды ls сохранен в файле, а после этого этот файл был обработан командой sort . Однако этот путь является неизящным и требует использования временного файла для хранения выходных данных программы ls .

Решением в данной ситуации может служить создание состыкованных команд (pipelines). Стыковку осуществляет командная оболочка, которая stdout первой команды направляет на stdin второй команды. В данном случае мы хотим направить stdout команды ls на stdin команды sort . Для стыковки используется символ, как это показано в следующем примере:

/home/larry/papers# ls | sort -r notes masters-thesis history-final english-list /home/larry/papers#

Эта команда короче, чем совокупность команд, и её проще набирать.

Рассмотрим другой полезный пример. Команда

/home/larry/papers# ls /usr/bin

выдаёт длинный список файлов. Большая часть этого списка пролетает по экрану слишком быстро, чтобы содержимое этого списка можно было прочитать. Попробуем использовать команду more для того, чтобы выводить этот список частями:

/home/larry/papers# ls /usr/bin | more

Теперь можно этот список «перелистывать».

Можно пойти дальше и состыковать более двух команд. Рассмотрим команду head , которая является фильтром следующего свойства: она выводит первые строки из входного потока (в нашем случае на вход будет подан выход от нескольких состыкованных команд). Если мы хотим вывести на экран последнее по алфавиту имя файла в текущем каталоге, можно использовать следующую длинную команду:

/home/larry/papers# ls | sort -r | head -1 notes /home/larry/papers\#

где команда head выводит на экран первую строку получаемого ей входного потока строк (в нашем случае поток состоит из данных от команды ls ), отсортированных в обратном алфавитном порядке.

Использование состыкованных команд (конвейер)

Эффект от использования символа для перенаправления вывода файла является деструктивным; иными словами, команда

/home/larry/papers# ls > file-list

уничтожит содержимое файла, если этот файл ранее существовал, и создаст на его месте новый файл.

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

/home/larry/papers# ls >> file-list

приписывает вывод команды ls в конец файла.

Следует иметь в виду, что перенаправление ввода и вывода и стыкование команд осуществляется командными оболочками, которые поддерживают использование символов, и. Сами команды не способны воспринимать и интерпретировать эти символы.

Недеструктивное перенаправление вывода

Что-то вроде этого должно делать то, что вам нужно?

Проверьте это: wintee

Нет необходимости в cygwin.

Однако я столкнулся и сообщил о некоторых проблемах.

Также вы можете проверить http://unxutils.sourceforge.net/ потому что он содержит tee (и не нужен cygwin), но будьте осторожны, что выходные EOL являются UNIX-подобными.

И последнее, но не менее важно, если у вас есть PowerShell, вы можете попробовать Tee-Object. Введите в консоли PowerShell для получения дополнительной информации.

Это работает, хотя это немного уродливо:

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

Я использую это довольно много в пакетных файлах для регистрации и отображения сообщений:

Да, вы могли бы просто повторить инструкцию ECHO (один раз для экрана и второй раз перенаправляясь на файл журнала), но это выглядит так же плохо, и это проблема обслуживания.

Перенаправление ввода и вывода

По крайней мере, таким образом вам не нужно вносить изменения в сообщения в двух местах.

Обратите внимание, что _ — это просто короткое имя файла, поэтому вам нужно будет удалить его в конце вашего пакетного файла (если вы используете пакетный файл).

Это создаст файл журнала с текущим временем и временем, и вы можете использовать линии консоли во время процесса

Если у вас есть cygwin в вашем пути к среде Windows, вы можете использовать:

Простое консольное приложение C # сделало бы трюк:

Чтобы использовать это, вы просто передаете исходную команду в программу и указываете путь к любым файлам, для которых вы хотите дублировать вывод. Например:

Будет отображать результаты поиска, а также сохранять результаты в файлах files1.txt и files2.txt.

Обратите внимание, что на пути обработки ошибок не так много (ничего!), И поддержка нескольких файлов может не потребоваться.

Я также искал одно и то же решение, после небольшой попытки, я смог успешно выполнить это в командной строке. Вот мое решение:

Он даже захватывает любую команду PAUSE.

Альтернативой является tee stdout для stderr в вашей программе:

Затем в вашем dos batchfile:

Stdout перейдет в файл журнала, и stderr (те же данные) отобразятся на консоли.

Как отобразить и перенаправить вывод в файл. Предположим, что если я использую команду dos, dir> test.txt, эта команда перенаправляет вывод в файл test.txt без отображения результатов. как написать команду для вывода вывода и перенаправления вывода в файл с помощью DOS, т. е. командной строки Windows, а не в UNIX / LINUX.

Вы можете найти эти команды в biterscripting (http://www.biterscripting.com) полезными.

Это вариант предыдущего answer MTS, однако он добавляет некоторые функции, которые могут быть полезны другим. Вот метод, который я использовал:

  • Команда задается как переменная, которая может использоваться позже в коде, для вывода в командное окно и добавления в файл журнала с использованием
    • команда избегает redirection с использованием символа моркови, чтобы команды не оценивались первоначально
  • Временной файл создается с именем файла, аналогичным пакетному файлу с именем который использует синтаксис расширения параметра командной строки чтобы получить имя командного файла.
  • Результат добавляется в отдельный файл журнала

Вот последовательность команд:

  1. Сообщения вывода и ошибки отправляются во временный файл
  2. Содержимое временного файла тогда равно:
    • добавлен в файл журнала
    • вывод в командное окно
  3. Временный файл с сообщением удаляется

Вот пример:

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

Это может быть добавлено и в конце других команд. Насколько я могу судить, это будет работать, когда сообщения имеют несколько строк. Например, следующая команда выводит две строки, если есть сообщение об ошибке:

Я согласен с Брайаном Расмуссеном, порт unxutils — самый простой способ сделать это. В разделе « Пакетные файлы » его страниц Scripting Rob van der Woude предоставляет массу информации об использовании команд MS-DOS и CMD. Я подумал, что у него может быть собственное решение вашей проблемы, и после того, как я TEE.BAT там копаться, я нашел TEE.BAT , который, кажется, именно так, представляет собой пакетный языковой пакет MS-DOS. Это довольно сложный пакетный файл, и я бы склонен использовать порт unxutils.

Я устанавливаю perl на большинстве своих машин, поэтому ответ с помощью perl: tee.pl

dir | perl tee.pl или каталог | perl tee.pl dir.bat

сырой и непроверенный.