LINUX.ORG.RU

Помогите разобраться с потоками

 , , ,


0

0

Всем привет! Совсем недавно начал знакомиться с Linux. Сейчас прохожу тему по потокам. Я вроде как понял, что нужно написать в командной строке, чтобы перенаправить вывод работы команды в файл или на вход другой команды и т. д., НО… До меня не очень доходит, как всё это в действительности работает. Я нарисовал себе следующую картину:

Есть какой-нибудь процесс (про процессы мало что знаю, ещё не дошёл до них), которому нужно принимать какие-то данные, обрабатывать их и отдавать результаты своей работы. Приём данных осуществляется через стандартный поток ввода (stdin), вывод результатов - через стандартный поток вывода (stdout). Насколько я понял, эти потоки есть ни что иное как файлы (ибо в Linux всё есть файл), откуда происходит считывание информации в случае с stdin и запись в файл в случае с stdout. Сами stdin, stdout неким образом (мне непонятно каким) по умолчанию связаны с клавиатурой и дисплеем соответственно. Но можно перенаправить данные потоки. Возьмём для примера перенаправление stdout в файл. В моей голове перенаправить значит отвязать stdout от дисплея и привязать его к какому-либо файлу. Как осуществляется это перепривязывание? И осуществляется ли оно вообще.

Есть вопрос по поводу выражения 2>&1. Как это понять? Т. е. на словах понятно, что происходит перенаправление стандартного потока ошибок на стандартный поток вывода. Но так сказать с технической точки зрения ничего непонятно. Попытаюсь объяснить, как я это понимаю.

Файл - именованная область данных на диске. Имя файла - указатель на данную область. При запуске процесса он (процесс) работает с файлами, которым присваиваются дескрипторы для идентификации файла в рамках работы данного процесса. Для stdin, stdout, stderr есть зарезервированные дескрипторы - 0, 1, 2 соответственно. Чтобы работать с этими файлами (stdin, stdout, stderr) используются их дескрипторы. Так вот, для меня строчка 2>&1 трактуется так: указатель stderr с дескриптором 2 перенаправить с дисплея на место, куда указывает указатель stdout (по умолчанию тоже дисплей, но не суть важно). Правильно? Думаю, нет. По крайней мере, звучит, как чепуха.

Ещё вопрос по выражению &> filename. Тяжело его понять. Хотя мне понятен смысл данной записи 1> filename 2>&1 (перенаправление stout, stderr в файл filename).

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

Подскажите, пожалуйста, прав я или нет. Исправьте, если надо. Правильно ли я понял, что стандартный поток ввода (stdin) и стандартный поток вывода (stdout) - файлы? Что значит перенаправить вывод/ввод процесса? Как именно осуществляется это перенаправление? В общем, помогите, пожалуйста, по возможности не вдаваясь в слишком глубокую теорию. Возможно, есть статьи, которые я не нашёл. Поделитесь, пожалуйста)))

В моей голове перенаправить значит отвязать stdout от дисплея и привязать его к какому-либо файлу. Как осуществляется это перепривязывание? И осуществляется ли оно вообще.

Это делает родительский процесс. В данном случае bash (или другой интерпретатор командной строки). И с помощью этого самого хитрого синтаксиса «> file», «2>&1», он меняет стандартные потоки дочернего процесса с дефолтных на какие-то другие

Harald ★★★★★ ()

Игры с файловыми дескрипторами идут через системные вызовы dup (man dup). Порождаемый процесс наследует открытые дескрипторы родителя, поэтому shell, перед запуском любой команды делает, чтобы 0,1,2 были связаны с каким нужно файлом.

Есть команда strace. Можете позапускать что-нибудь (допустим sh-скрипт, который запукает простую команду с выводом в файл) под strace (с трассировкой потомков и выводом в файлы), будет понятно, как что происходит.

Правильно ли я понял, что стандартный поток ввода (stdin) и стандартный поток вывода (stdout) - файлы?

Да, файлы. Если это терминал, то это специальные файлы (из каталога /dev). В каталоге /proc/PID/fd указаны какие файлы с каким дескриптором в данный момент у процесса связаны.

mky ★★★★★ ()

Файл – абстрактное понятие, которое определяет общий интерфейс. За ним может стоять как данные на диске, так и кусок памяти или виртуальное устройство. Дескрипторы идентифицируют файлы в ядре с точки зрения программы. Программа лишь говорит ядру «прочитать из/записать в такой дескриптор», а ядро уже либо читает реальный файл, либо отдаёт данные другому процессу через буфер в памяти, либо общается с устройством.

Всё что делает перенаправление, так это конфигурирует какие из возможных «реализаций» файлов в ядре соответствуют каким дескрипторам.

Есть вопрос по поводу выражения 2>&1. Как это понять?

Дескриптор №2 будет указывать в ядре туда же, куда сейчас указывает дескриптор №1.

Ещё вопрос по выражению &> filename. Тяжело его понять. Хотя мне понятен смысл данной записи 1> filename 2>&1

Это просто специальный синтаксис для второго выражения.

xaizek ★★★★★ ()

в целом ты всё правильно понимаешь. когда почитаешь про процессы, таблицу дескрипторов, про то как порождаются процессы, то всё прояснится.

anonymous ()