Андрей Михайлович Васильев, 2023
Версии презентации
В момент запуска процесса ему выделяются стандартные потоки для ввода и вывода информации
0, stdin — стандартный поток ввода1, stdout — стандартный поток вывода2, stderr — стандартный поток вывода сообщений об ошибкахПроцесс, инициирующий запуск другого процесса, определяет на какие файловые дескрипторы будут переданы работающему процессу
Процесс во время своей работы может самостоятельно изменить направление потоков, однако эта возможность используется в основном управляющими процессами (например интерпретатором Bash)
System.out.println("Текст выведен на стандартный поток вывода")
System.err.println("Текст выведен на поток ошибок")import sys
print("Текст на стандартный поток вывода")
print("Текст на поток ошибок", file=sys.stderr)#include <stdio.h>
int main() {
printf("Поток вывода\n");
fprintf(stderr, "Поток ошибок\n");
}В Linux для создания нового процесса используется системный вызов:
#include <unistd.h>
pid_t fork(void);
Процесс-ребёнок разделяет с процессом-родителем все ресурсы, включая:
exec*)Эмулятор терминала общается с пользователем только по двум каналам:
Если специальных действий не было предпринято, тогда
stdout и stderr выводится на экран в историиС точки зрения пользователя потоки stdout и stderr выводятся как результат работы приложения, ничем не отличимые друг от друга
Если данные с потоков приходят одновременно, то возможно их пересечение, обычно происходит путём чередования строк
ls
#
Приложение ls не использует стандартный поток ввода, данные ему передаются исключительно через аргументы
stdout используется для вывода списка файловstderr используется для вывода информации об ошибкахПример вывода на стандартный поток вывода:
$ ls -1 /tmp
mc-andrey
mozilla_andrey0
...Пример вывода на поток ошибок:
$ ls /abc
ls: невозможно получить доступ к '/abc': Нет такого файла или каталогаБез применения специальных действий различить два вывода мы не сможем
Bash позволяет перенаправить поток вывода любой команды в файла
КОМАНДА > output_log.txtРезультат работы команды будет записан в файл output_log.txt
ls
#
$ ls -l /usr/bin > /tmp/ls-output.txt
$В результате запуска пользователю не будет выведено никакой информации, а она будет записана в файл /tmp/ls-output.txt
echo
#
Поток вывода можно перенаправлять и для встроенных команд Bash
echo 'Hello, world!' > text.txtВ результате будет создан файл text.txt с содержимым 'Hello, world!'
Помимо touch можно воспользоваться перенаправлением вывода для создания пустых файлов
> empty.txtПустая команда не выводит ничего, в результате будет создан файл empty.txt
С технической точки зрения перенаправление потока выглядит следующим образом:
>w, запись с начала
Помимо перезаписи файла Bash может добавлять результаты в конец текстового файла
Синтаксис:
КОМАНДА >> output_log.txtСтандартный поток вывода будет записан в конец файла output_log.txt
В отличие от предыдущей формы файл открывается с флагом a
ls
#
$ ls -l /usr/bin > ls-output.txt
$ ls -l /usr/bin >> ls-output.txtВ результате выполнения этой последовательности в файле ls-output.txt будет находиться два вывода результата запуска команды ls -l /usr/bin
stderr
#
stderr
#
$ ls -l /some > ls-info.txt
ls: невозможно получить доступ к '/some': Нет такого файла или каталогаХотя stdout был перенаправлен, но приложение всё-равно вывело информацию пользователю
Синтаксис:
КОМАНДА 2> error-info.txtВ результате будет создан файл error-info.txt, содержащий информацию из потока stderr запущенной команды
Все данные из потока stdout будут показаны пользователю
Для решения этой задачи надо сначала перенаправить stdout в один файл, а затем перенаправить поток stderr в поток stdout:
КОМАНДА > output.txt 2>&1Форма записи 2>&1 говорит, что поток №2 надо связать с потоком №1
КОМАНДА 2>&1 > output.txtТакая запись свяжет сначала поток ошибок со стандартным потоком вывода, а после уже перенаправит поток вывода в файл output.txt. В результате будет перенаправлен только стандартный поток вывода
Если надо перенаправить все потоки в один файл, то можно воспользоваться &>:
КОМАНДА &> output.txtКОМАНДА &>> output.txtВ результате запуска весь вывод будет добавлен в конец файла output.txt
Бывает так, что приложение посылает много информации на поток stderr и мы хотим его игнорировать. Для этих целей можно воспользоваться специальным файлом /dev/null:
КОМАНДА 2> /dev/nullВсе данные, которые записываются в файл /dev/null, пропадают. Это могут использовать любые приложения
cat
#
$ cat --help
Использование: cat [КЛЮЧ]… [ФАЙЛ]…
Печатает слияние ФАЙЛ(ов) на стандартный вывод.Приложение считывает файлы, пути к которым переданы через аргументы, и выводит результат на стандартный поток вывода
Самое простое применение — чтение текстовых файлов
Если не cat не указать файлы, то оно берёт информацию со стандартного потока ввода
Если перенаправить поток вывода в файл, то данные с потока ввода будут сразу записываться в файл
cat > data.txtДля завершения работы приложения надо послать сигнал завершения потока Ctrl+D
Для перенаправления потока ввода у процесса надо использовать следующий синтаксис:
КОМАНДА < input.txtВ результате поток ввода будет команды будет получать данные из файла input.txt
Вместе с cat его можно использовать для чтения файла:
$ cat < input.txt
...При написании консольных программ часто приходится повторять одни и те же действия для проверки работы приложения. Для решения этой задачи удобно
В этом случае вам не придётся повторять ввод данных множество раз
Большинство интерактивных приложений могут использовать другие способы по взаимодействию с пользователем и не поддерживают такой формат тестирования, но предоставляют более удобные псевдографические элементы для взаимодействия
pipe
#
Помимо соединения потоков ввода и вывода с файлами Bash (операционная система) позволяет соединять поток вывода одного процесса с потоком ввода другого процесса
Данный механизм называется pipe, конвеер
В Bash для связи потоков двух процессов используется оператор |:
КОМАНДА-1 | КОМАНДА-2В результате будут запущены КОМАНДА-1 и КОМАНДА-2, причём стандартный вывод КОМАНДА-1 будет подключён ко входу в конвеер, а выход конвеера подключён к стандартному входу программы КОМАНДА-2
Результат выполнения команды может не поместиться на экран, вследствие чего пользователю приходится просматривать предыдущий вывод
Ctrl + Page Up, Ctrl + Page DownShift + Page Up, Shift + Page DownПриложение less позволяет просматривать не только текстовые файлы, но также и длинный ввод со стандартного потока
Чтобы найти нужную информацию в потоке данных их можно передать less
ls -l /usr/bin | lessДля удобной обработки текстовой информации, приходящей от приложений в UNIX можно использовать приложения, нацеленные на обработку потока строк, приходящих на стандартный поток ввода
Благодаря конвеерам эти приложения зачастую объединяются
КОМАНДА | ФИЛЬТР-1 | ФИЛЬТР-2 | ФИЛЬТР-3Фильтры ориентированы на работу со структурированными данными
sort
#
Приложение сортирует входящий поток строк
Рассмотрим текстовый файл data.txt:
euo
aoeu
zeouСортировка файла:
$ cat data.txt | sort
aoeu
euo
zeouuniq
#
Выбрасывает из входящего потока данных повторяющиеся строки. Зачастую используется вместе с sort
Исходный файл:
abc
abc
def
abc
def
def
defОтброс с сортировкой:
> cat data.txt | sort | uniq
abc
defОтброс без сортировки:
> cat data.txt | uniq
abc
def
abc
defwc
#
Приложение wc предназначено для вычисления статистических харакретистик в файле или потоке данных:
Для поиска уникально названных исполняемых файлов из каталогов /bin и /usr/bin можно воспользоваться командой
$ ls /bin /usr/bin | sort | uniq | wc -l
3846grep
#
$ grep --help
Использование: grep [ПАРАМЕТР]… ШАБЛОНЫ [ФАЙЛ]…
Поиск ШАБЛОНОВ в каждом ФАЙЛЕ.
Пример: grep -i 'hello world' menu.h main.c> ls /bin /usr/bin | sort | uniq | grep zip
bunzip2
bzip2
bzip2recover
funzip
gpg-zip
gunziphead
#
Приложение head показывает первые строки файла или стандартного потока ввода
Для управления количеством показываемых линий используется аргумент -n
$ ls /usr/bin | head -n 4
[
411toppm
7z
7zatail
#
Приложение tail показывает последние строки файла или стандартного потока ввода
$ ls /usr/bin | tail -n 4
zipnote
zipsplit
zoom
zshНекоторые приложения постоянно записывают информацию в файл, например для ведения журнала своей деятельности
Приложение tail позволяет следить за изменениями в файле
tail -f info.logВ одной консоли будем следить за состоянием файла:
$ touch work.log
$ tail -f work.log
abc
def
def
tail: work.log: файл усечён
infoВ другой консоли будем изменять данный файл:
$ echo 'abc' > work.log
$ echo 'def' >> work.log
$ echo 'def' >> work.log
$ echo 'info' > work.logtee
#
Термином tee называется Т-образный отвод трубопровода
Приложение tee принимает данные на стандартный поток ввода, а затем записывает их на стандартный поток вывода и в файл на жёстком диске
Это приложение удобно использовать для отслеживания промежуточного или финального состояния команды, использующей конвееры
$ ls /usr/bin | grep zip | tee -a zip-list | wc -l
21
$ cat zip-list
funzip
gpg-zip
lzip
...awk
#
AWK — это инструмент и скриптовый язык, предназначенный для работы с текстовыми документами
$ cat workers.txt
Василий менеджер 10000
Иван разработчик 5000
Ира аналитик 5500
Михаил разработчик 5100
Степан аналитик 5400$ awk '{print $1,$3}' workers.txt
Василий 10000
Иван 5000
Ира 5500
Михаил 5100
Степан 5400sed
#
Данный текстовый редактор позволяет выполнять операции над отдельными строками в файле или в потоке данных
$ sed --help
Использование: sed [ПАРАМЕТР]… {только-сценарий-если-нет-другого-сценария} [входной-файл]…
...$ cat info.txt
linux is great os. unix is opensource. unix is free os.
learn operating system.
linux linux which one you choose.
linux is easy to learn.unix is a multiuser os.Learn unix
$ cat info.txt | sed 's/unix/linux/2'
linux is great os. unix is opensource. linux is free os.
learn operating system.
linux linux which one you choose.
linux is easy to learn.unix is a multiuser os.Learn linux