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

  • 25.01.2022

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

Команда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 - соответственно смыслу) должна начинаться с начала строки.

Если вывод в (графическую) консоль не очень объёмный, можно просто выдельть мышкой кусок и вставить его в сообщение щелчком средней кнопки. В противном случае можно использовать перенаправление вывода в файл через "воронку", например так:

Some_command parameters > logfile.txt

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

Some_command parameters | tee -a logfile.txt

Команда setterm -dump создает "слепок" буфера текущей виртуальной консоли в виде простого текстового файла с именем по умолчанию - screen.dump. В качестве ее аргумента можно использовать номер консоли, для которой требуется сделать дамп. А добавление опции -file имя_файла перенаправит этот дамп в файл с указанным именем. Опция же -append присоединит новый дамп к уже существующему файлу - "умолчальному" screen.dump или поименованному опцией -file .

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

Setterm -dump -file /root/screenlog

соответственно в файле /root/screenlog будет содержимое одной страницы консоли.

Нашёл еще одно решение для копирования/вставки текста в текстовой консоли без мыши. Также можно копировать текст из буфера прокрутки (т.е. всё что на экране и выше за экраном). Чтобы лучше разобраться, читайте о консольном менеджере окон screen . Также может пригодиться увеличить размер буфера прокрутки.

1) Запускаем screen

2) Нажимаем Enter. Всё. Мы находимся в нулевом окне консоли.

3) Выполняем нужные команды, вывод которых необходимо скопировать.

4) Ctrl+A, Ctrl+[ - мы в режиме копирования. Ставим курсор на начало выделения, жмём пробел, потом ставим курсор на конец выделения, жмём пробел. Текст скопирован в буфер.

5) Ctrl+A, с - мы создали новое 1-е окно.

6) Ctrl+A, 1 - мы перешли на 1-е окно.

7) Открываем любой (?) текстовый редактор (я пробовал в mc), и жмём Ctrl+A, Ctrl+] - текст вставлен. Сохраняем.

8) Ctrl+A, Ctrl+0 - вернуться обратно в нулевое окно.

Как увеличить буфер обратной прокрутки?

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

И такое средство есть, а называется оно framebuffer console , для краткости fbcon . Это устройство имеет файл документации fbcon.txt ; если вы устанавливали документацию к ядру, то он у вас есть. Выискивайте его где-то в районе /usr/share ветви (я не могу указать точный путь из-за разницы в дистрибутивах).

На этом месте прошу прощения: мы должны сделать небольшое отступление и немного поговорить о видеобуфере (framebuffer ).

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

Один из таких трюков связан с буфером прокрутки; оказывается, вы можете "попросить" видеобуфер выделить больше памяти буферу прокрутки. Достигается это через загрузочные параметры ядра. Сначала вы требуете framebuffer (видеобуфер); Затем запрашиваете больший буфер прокрутки.

Нижеследующий пример касается GRUB , но может быть легко адаптирован к LILO . В файле настройки GRUB - menu.lst - найдите соответствующую ядру строчку, и затем: Удалите опцию vga=xxx , если таковая присутствует. Добавьте опцию video=vesabf или то, что соответствует вашему "железу". Добавьте опцию fbcon=scrollback:128 . После этой процедуры, строка параметров ядра должна выглядеть приблизительно так:

Kernel /vmlinuz root=/dev/sdb5 video=radeonfb fbcon=scrollback:128

Спрашивается, зачем удалять опцию vga=xxx ? Из-за возможных конфликтов с видео-опцией. На своем ATI адаптере, я не могу изменить буфер прокрутки, если vga=xxx присутствует в списке. Возможно в вашем случае это не так. Если вышеперечисленные опции работают - хорошо; но что, если вы хотите увеличить число строк, или установить более мелкий шрифт на экране? Вы всегда делали это при помощи опции vga=xxx - а она-то и исчезла. Не переживайте - то же самое может быть достигнуто изменением параметров fbcon, как описано в файле fbcon.txt (но не описано в данной статье).

С опцией fbcon=scrollback:128 у меня буфер прокрутки увеличился до 17 экранов (35 раз Shift+PgUp по полэкрана). Кстати, 128 - это килобайт. Автор статьи утверждает, что больше установить нельзя. Я и не пробовал.

Можно заюзать script .

Script filename.log

когда все нужные команды выполнены -

Все записано в filename.log

В FreeBSD есть замечательная утилита watch, которая позволяет мониторить терминалы, но как оказалось, в Linux она выполняет совсем иные функции =\ Стоит погуглить на эту тему, чего-нть да найдется...

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


Чтобы начать запись нужно выполнить команду script . Если вызвать команду script без параметров, то запись будет вестись в файл с именем typescript.


$ script
Скрипт запущен, файл - typescript

Файл будет создан именно в той директории, в которой вы находитесь. Вывести название текущей директории можно командой pwd. Если файл уже существует, то он будет очищен.


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


script terminal.log

После ввода команды будет создан файл, но данные в него будут записаны только после того, как вы введете команду exit или нажмете сочетание клавиш Ctrl+D. Пример:


$ script
Скрипт запущен, файл - typescript
$ pwd
/home/user
$ exit
exit
Скрипт выполнен, файл - typescript
$

Мы выполнили команду script. Автоматически был создан файл typescript (если он уже существовал, то он будет очищен). С этого момента система начинает запоминать весь ввод и вывод в терминале. В конце мы вводим команду exit и в файл с именем typescript записывается все, что происходило в терминале с момента ввода команды script.


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


$ script my.log <--- Первый вызов: создается пустой файл my.log

$ ifconfig
eth0 Link encap:Ethernet HWaddr bb:aa:cc:dd:aa:bb
..
$ exit <--- Данные записываются в файл my.log
exit

$ script my.log -a <--- Второй вызов с опцией -a. Файл не очищается.
Скрипт запущен, файл - my.log
$ pwd
/home/user
$ exit
exit

Скрипт выполнен, файл - my.log <--- Данные добавляются к содержимому my.log

Еще стоит сказать о полезной опции -c или —command . Данная опция позволяет указать команду, которую нужно выполнить, а вывод этой команды записать файл. Пример:


$ script my.log -c ls
Скрипт запущен, файл - my.log
my.logtemp Ubuntu OneИзображения
ЗагрузкиРабочий стол
Скрипт выполнен, файл - my.log

В данном примере мы вызываем команду script с опцией -c и указываем в качестве параметра опции команду ls , которую нужно выполнить, а вывод команды нужно записать в файл my.log. Команда ls выводит список файлов в текущей директории. Таким образом в файл my.log попадет список файлов.


Получить справку по команде script (по всем ее опциям) можно, выполнив в терминале:

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

Вариант 1: только перенаправляем вывод терминала в файл

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

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

Оператор >> перенаправит вывод команды в файл, и если в нем также будет находиться информация, новые данные будут добавлены в конец файла.

Рассмотрим на примере команды ls , которая отображает список файлов и папок в указанной директории. Давайте запишем результат ее работы в текстовый файл. Нам нужно написать команду, поставить оператор и указать путь к файлу:

Ls > /home/ruslan/пример

Теперь посмотрим, все ли сработало. Для этого можно воспользоваться любым текстовым редактором, какой у вас есть. Также это можно сделать прямо в терминале при помощи команды cat:

Cat /home/ruslan/пример

Все работает.

Помните, что «> » перезапишет все данные, которые были до этого в файле, поэтому, если вам нужно дописать что-либо в файл используйте оператор «>> «

Допустим, что после того, как мы перенаправили вывод команды ls в файл «пример » мы решили узнать версию ядра системы и также сохранить вывод в тот же файл. Чтобы узнать версию ядра воспользуемся командой uname и параметром -a , затем говорим Bash как и куда нужно сохранить результат ее выполнения:

Uname -a >> /home/ruslan/пример

Снова проверим результат:

Cat /home/ruslan/пример

Как видим, у нас сохранились результаты работы и ls , и uname .

Вариант 2: перенаправляем вывод в файл и отображаем его на экране

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

Команда | tee /путь/к/файлу

Этот вариант подобен оператору > из предыдущего пункта, то есть при записи в файл, все старые данные будут удалены. Если вам нужно дописать в файл, в конструкцию нужно добавить параметр -a :

Команда | tee -a /путь/к/файлу

Система ввода/вывода в LINUX .

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

Каждому подключенному устройству (терминалу, дискам, принтеру и т. д.), соответствует, как минимум, один специальный файл. Большая часть этих специальных файлов хранится в каталоге /dev:
$ cd /dev
$ ls -l
onsole пульт управления системы
dsk порции на диске
fd0 флоппи-диск 1
mem память
lр принтер
lр0 параллельный порт 0
. . .
root порция на диске для корневой файловой системы
swap своп-порция
syscon альтернативное имя пульта
systty еще одно имя для системной консоли
term директория для терминалов
ttyS0 серийный порт 0 (COM1)
. . .

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

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

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

На одном диске можно создать несколько файловых систем. Некоторые системы используют по одной файловой системе на диске, а другие - по несколько. Новую файловую систему можно создать с помощью команды mkfs (make file system). Например, выражение # /sbin/mkfs /dev/dsk/fl1 512 означает: создать на флоппи-диске b: размером в 512 блоков.

По желанию можно задать размер файловой системы в блоках и количество i-узлов (т. е. максимальное число файлов, которые могут быть сохранены в файловой системе). По умолчанию число i-узлов равно числу блоков, деленному на четыре. Максимальное число i-узлов в одной файловой системе 65 000. Если по некоторым причинам вам необходимо более 65000 i-узлов на диске, необходимо создать две или более файловые системы на этом диске.

Всякая файловая система может быть прикреплена (монтирована) к общему дереву каталогов, в любой его точке. Например, каталог / - это корневой (root) каталог системы, кроме этого, он является основанием файловой системы, которая всегда монтирована. Каталог /usr1 находится в каталоге /, но в данном случае является отдельной файловой системой от корневой файловой системы, так как все файлы в нем находятся на отдельной части диска или вообще на отдельном диске. Файловая система /usr1 - монтируемая файловая система - корень в точке, где каталог /usr1 существует в общей иерархии (рис. 1 и 2).

Рис. 1. Файловая система перед
монтированием /dev/dsk/os1

Рис. 2. Файловая система после
монтирования /dev/dsk/os1 как /usr/

Для монтирования файловой системы используется команда /sbin/mount. Эта команда разрешает расположить данную файловую систему везде в существующей структуре каталогов:
#/sbin/mount/dev/dsk/osl/usr1 монтирует /dev/dsk/osl на /usr1
#/sbin/mount/dev/dsk/flt/а монтирует /dev/dsk/flt на /а

Если нужно монтировать файловую систему на диски, которые должны быть защищены от записи, чтобы система была доступна только для чтения, необходимо добавить опцию - r к команде /sbin/mount.
Каталог, к которому прикрепляется монтируемая файловая система, должен быть в данный момент пустой, так как содержимое его будет недоступно, пока файловая система монтируется.

Чтобы получить информацию о файловых системах, которые смонтированы, например, на системе LINUX, можно использовать команду /sbin/mount без аргументов (рис. 3).

Рис. 3.

Эта команда выводит каталог, на который была смонтирована файловая система (например, usrl), устройство /dev, на котором она находится, час и дата, когда она была смонтирована. Для демонтирования файловой системы используется команда /sbin/umount, которая имеет обратное действие по отношению к команде mount. Она освобождает файловую систему и как бы вынимает ее целиком из структуры каталогов, так что все ее собственные файлы и каталоги становятся недоступны:
# /sbin/umount /b
# /sbin/umount /dev/dsk/0s2

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

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

Для физических устройств в LINUX существуют директории dsk и rdsk, которые содержат файлы, соответствующие дисковым устройствам. Обыкновенно имена файлов в этих директориях одинаковы и единственная разница между ними, что директория rdsk содержит дисковые устройства со специальным доступом (raw), который используют некоторые устройства системы для более быстрого доступа к диску. Одна типичная директория dsk содержит следующие устройства:
$ 1s /dev/dsk
0s0 1s0 c0t0d0s0 c0tld0s0 f0 f05q f13dt fld8d
0sl 1sl c0t0d0sl c0tld0sl f03d f05qt f13h fld8dt
0s2 1s2 c0t0d0s2 c0tld0s2 f03dt f0d8d f13ht fld8t
. . .
$

B системе LINUX дисковые устройства логически разделены на секции, подобно разделам определяемым в Partition Table MasterBoot MS DOS. Файлы 0s1, 0s2, 0s3 и т. д, соответствуют секциям первой, второй, третьей и т. д. диска с номером 0. Файлы 1s0, 1sl, 1s2 и т. д. соответствуют секциям первой, второй, третьей и т. д. диска с номером 1. Если система имеет больше дисков, секции будут пронумерованы ns0, nsl и т. д. для каждого диска с номером n.

Системы с большим количеством дисковых устройств используют следующую систему нумерации:
с controller d disk s section

где controller - номер контроллера диска; disk - номер диска; section -номер секции диска.
Так, 0s0 обычно эквивалентно c0t0d0s0, а 0sl - c0t0d0sl, и трехсимвольные имена секций - это просто сокращение для дискового контроллера с номером 0.

Файлы, имена которых начинаются с f, определяют различные виды гибких дисков. Каталог rmt содержит файлы на устройствах типа магнитная лента:
$ 1s /dev/rmt
c0s0 cls0 c3s0 ntape ntapel tape tapel

Файлы c0s0, cls0, c2s0 и c3s0 определяют четыре кассетных ленточных запоминающих устройства. Файлы tape и tapel определяют магнитные запоминающие устройства с двумя бобинами. Файлы, чьи имена начинаются с n, относятся к тем же устройствам, только лента не перематывается после использования, в то время как использование других файлов заставляет ленту перематываться, когда использующая ее программа заканчивает работу.

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

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