- Русские Блоги
- Подробные файловые дескрипторы Linux
- Overview
- Стандартные файловые дескрипторы Linux
- Некоторые команды оболочки, связанные с файловыми дескрипторами
- Разница между каналами и перенаправлениями
- 11.2.1. Файловые дескрипторы
- Читайте также
- 4.4.2.1. Отображение переменных FILE* на дескрипторы файлов
- Наследуемые дескрипторы
- Абсолютные и самоопределяющиеся относительные дескрипторы безопасности
- 11.2.1. Файловые дескрипторы
- Индексные дескрипторы
- Виртуальные индексные дескрипторы
- 2.5 Индексные дескрипторы
- 16.3. Индексные дескрипторы файлов
- Файловые таблицы
- 1.1.3. Дескрипторы вместо классов
- Файловые менеджеры
- 7.2.5. Дескрипторы файлов процесса
- 6.5. Файловые структуры
- 6.6. Файловые системы
- Файл дескриптор в Linux с примерами
- Тузик
- Файл дескриптор
- Redirect и Pipe
- Программируем уже запущенный процесс
- Немного усложним задачу
Русские Блоги
Подробные файловые дескрипторы Linux
Заявление об авторском праве: Пожалуйста, укажите источник при перепечатке, спасибо https://blog.csdn.net/xlinsist/article/details/51147212
Overview
Важно понимать, как Linux обрабатывает ввод и вывод. Как только мы поймем принцип, мы сможем правильно и умело использовать сценарий, чтобы вывести содержимое в нужное место. Мы также можем лучше понять перенаправление ввода и перенаправление вывода.
Стандартные файловые дескрипторы Linux
Дескриптор файла | сокращение | описание |
---|---|---|
0 | STDIN | Стандартный ввод |
1 | STDOUT | Стандартный вывод |
2 | STDERR | Стандартный вывод ошибок |
Системы Linux рассматривают все устройства как файлы, а Linux использует файловые дескрипторы для идентификации каждого файлового объекта. Фактически, мы можем представить, что дисплей и клавиатура нашего компьютера рассматриваются как файлы в системе Linux, и все они имеют соответствующие файловые дескрипторы, соответствующие им.
На самом деле наше взаимодействие с компьютером заключается в том, что я могу вводить некоторые инструкции, и это дает мне некоторую информацию. Тогда мы можем поставитьФайловый дескриптор 0 понимается как мой ввод при взаимодействии с компьютером, и этот ввод по умолчанию направлен на клавиатуру; Файловый дескриптор 1 понимается как вывод, когда я взаимодействую с компьютером, и этот вывод по умолчанию направляется на дисплей; Файловый дескриптор 2 понимается как выходная информация об ошибке компьютера, когда я взаимодействую с компьютером, и этот вывод по умолчанию соответствует местоположению, указанному файловым дескриптором 1;
Как я уже говорил выше, так как они по умолчанию, я могу их изменить. Следующая команда изменяет расположение стандартного вывода в файл xlinsist:
На этот раз, если я войду ls -al или ps Команда, наш терминал не будет ничего отображать. Теперь мы можем открыть новый терминал и посмотреть, есть ли в файле xlinsist содержимое, показанное в двух приведенных выше командах.Примечание: вы должны открыть новый терминал.
Таким же образом мы также можем изменить положение стандартного ввода. Во-первых, давайте посмотрим на то, что не изменилось:
То есть мы читаем xlinsist в пользовательскую переменную с клавиатуры. Это чтение требует моего ввода. Теперь я хочу изменить стандартную позицию стандартного ввода:
Как вы можете видеть из приведенной выше команды чтения, меня ни о чем не просили.
Разница между стандартным выводом ошибки и стандартным выводом заключается в том, что он выводится в случае ошибки команды. Это не так уж отличается, мы также можем изменить его вывод в любое место, которое мы хотим. Просто нам нужно изменить стандартный вывод с 1 на 2. Команда выглядит следующим образом:
- Конечно, в дополнение к 0, 1, 2 мы можем выделить наши собственные файловые дескрипторы. Посмотрите на следующий пример:
Вышеприведенная команда очень интересна: сначала я указываю дескриптор файла 6 на тестовый файл. Поскольку в отличие от дескриптора 1, все выходные данные будут естественно искать его и видеть, направлен ли он на экран или в файл. Поэтому, когда мы хотим найти дескриптор 6, нам нужно использовать & для ссылки на него. Фактически, мы можем рассматривать дескриптор файла как ссылку на файл, который может указывать на любой файл (включая отображение). Процесс наведения — это процесс изменения местоположения по умолчанию. И используйте амперсанд, чтобы найти целевой файл, на который он указывает, и записать в него данные.
Если вы действительно понимаете вышеприведенные принципы, мы можем воспроизвести любое перенаправление ввода, перенаправление вывода, и это небольшой случай. Теперь давайте возьмем более сложный пример, чтобы помочь вам организовать ваши идеи. Сценарий выглядит следующим образом:
Давайте разберемся с вышеприведенной командой шаг за шагом: во-первых, дескриптор файла 1 по умолчанию указывает на монитор. Используйте &, чтобы найти целевой файл, на который указывает дескриптор файла 1, который является монитором. Таким образом, дескриптор файла 3 также указывает на отображение. Затем мы изменили файл, на который указывает дескриптор файла 1, в тестовый файл. Затем выходные данные двух команд echo будут естественно искать дескриптор файла 1, а затем он обнаруживает, что дескриптор файла 1 указывает на тестовый файл, поэтому он записывает выходные данные в тестовый файл. Наконец, мы используем &, чтобы найти целевой файл, на который указывает дескриптор файла 3, который является дисплеем, и затем мы модифицируем файл, на который указывает дескриптор файла 1, для отображения. Следовательно, последняя команда echo естественным образом найдет дескриптор файла 1 и выведет его на дисплей.
Весь процесс таков, пока вы понимаете их принципы, вы не будете чувствовать растерянность, независимо от того, как вы будете обрабатывать перенаправления в сценариях в будущем. Ниже я представлю некоторые команды оболочки, относящиеся к файловым дескрипторам, которые могут сделать вас еще более мощным.
Некоторые команды оболочки, связанные с файловыми дескрипторами
На следующем рисунке показано значение вышеперечисленных пунктов
Теперь я модифицирую стандартный вывод ошибок:
Файл / dev / null, это очень специальный файл, все, что вы пишете, будет очищено. Вы можете записать данные, чтобы попробовать эффект.
- Мы можем перенаправить стандартный вывод ошибок в / dev / null, тем самым отбрасывая сообщения об ошибках, которые мы не хотим сохранять
- Мы можем быстро удалить данные из существующих файлов без предварительного удаления файла при его создании. Команда выглядит следующим образом:
Linux использует каталог / tmp для хранения файлов, которые не нужно хранить постоянно. Большинство систем Linux автоматически удаляют все файлы в каталоге / tmp при запуске.
Доступны следующие команды:
tee команда-чтение из стандартного ввода, запись в стандартный вывод и файлы.
Разница между каналами и перенаправлениями
Канал — это выход одной программы как вход другой программы.
Перенаправление — это перенаправление вывода в файл или стандартный поток.
Источник
11.2.1. Файловые дескрипторы
11.2.1. Файловые дескрипторы
Когда процесс получает доступ к файлу (что обычно называют открытием файла), то ядро возвращает ему файловый дескриптор, который затем используется процессом для всех операций с файлом. Файловые дескрипторы — это маленькие положительные целые числа, которые служат индексами массива открытых файлов, создаваемого ядром для каждого процесса.
Первые три файловых дескриптора для процессов (0, 1 и 2) имеют стандартное назначение. Первый, 0, известен как стандартный ввод (stdin) и является местом, откуда программы должны получать свой интерактивный ввод. Файловый дескриптор 1 называется стандартным выводом (stdout), и большая часть вывода программ должна быть направлена в него. Сообщения об ошибках должны направляться в стандартный поток ошибок (stderr), который имеет файловый дескриптор 2. Стандартная библиотека С следует этим правилам, поэтому gets() и printf() используют stdin и stdout соответственно, и это соглашение дает возможность командным оболочкам правильно перенаправлять ввод и вывод процессов.
Заголовочный файл представляет макросы STDIN_FILENO, STDOUT_FILENO и STDERR_FILENO, которые вычисляются как файловые дескрипторы stdin, stdout и stderr соответственно. Использование этих символических имен делает код более читабельным.
Многие из файловых операций, которые манипулируют файловыми узлами inode, доступны в двух формах. Первая форма принимает в качестве аргумента имя файла. Ядро использует этот аргумент для поиска inode файла и выполняет соответствующую операцию над ним (обычно это включает следование символическим ссылкам). Вторая форма принимает файловый дескриптор в качестве аргумента и выполняет операцию над inode, на который он ссылается. Эти два набора системных вызовов используют похожие имена, но системные вызовы, работающие с файловыми дескрипторами, имеют префикс f. Например, системный вызов chmod() изменяет права доступа для файла, ссылка на который осуществляется по имени; fchmod() устанавливает права доступа к файлу, ссылаясь на него по указанному файловому дескриптору.
Чтобы меньше тратить слов, мы представим обе версии системных вызовов, если они существуют, а обсуждать будет только первую из их (та, которая использует имена файлов).
Читайте также
4.4.2.1. Отображение переменных FILE* на дескрипторы файлов
4.4.2.1. Отображение переменных FILE* на дескрипторы файлов Стандартные библиотечные функции ввода/вывода и переменные FILE* из , такие, как stdin, stdout и stderr, построены поверх основанных на дескрипторах файлов системных вызовах.Иногда полезно получить непосредственный
Наследуемые дескрипторы
Наследуемые дескрипторы Часто бывает так, что дочернему процессу требуется доступ к объекту, к которому можно обратиться через дескриптор, определенный в родительском процессе, и если этот дескриптор — наследуемый, то дочерний процесс может получить копию открытого
Абсолютные и самоопределяющиеся относительные дескрипторы безопасности
Абсолютные и самоопределяющиеся относительные дескрипторы безопасности Программа 15.5, позволяющая изменять ACL, удобна тем, что просто заменяет один дескриптор безопасности (SD) другим. В то же время, при замене существующих SD следует проявлять осторожность, поскольку они
11.2.1. Файловые дескрипторы
11.2.1. Файловые дескрипторы Когда процесс получает доступ к файлу (что обычно называют открытием файла), то ядро возвращает ему файловый дескриптор, который затем используется процессом для всех операций с файлом. Файловые дескрипторы — это маленькие положительные целые
Индексные дескрипторы
Индексные дескрипторы Индексный дескриптор, или inode, содержит информацию о файле, необходимую для обработки данных, т.е. метаданные файла. Каждый файл ассоциирован с одним inode, хотя может иметь несколько имен в файловой системе, каждое из которых указывает на один и тот же
Виртуальные индексные дескрипторы
Виртуальные индексные дескрипторы Дисковый файл обычно имеет связанную с структуру данных, называемую метаданными или inode, где хранятся основные характеристики данного файла и с помощью которой обеспечивается доступ к его данным. Одним из исключений из этого правила
2.5 Индексные дескрипторы
2.5 Индексные дескрипторы Файл имеет несколько атрибутов: имя, содержимое и служебную информацию (права доступа и даты модификации). Служебная информация размещается в индексном дескрипторе вместе с важной системной информацией, такой, как размер файла, место хранения
16.3. Индексные дескрипторы файлов
16.3. Индексные дескрипторы файлов Каждому файлу на диске соответствует один и только один индексный дескриптор файла, который идентифицируется своим порядковым номером — индексом файла. Это означает, что число файлов, которые могут быть созданы в файловой системе,
Файловые таблицы
Файловые таблицы Эта группа таблиц содержит информацию обо всех файлах, составляющих программный продукт. Большая часть этих файлов перечислена в таблице File. Таблица Directory не входит в эту группу, но, тем не менее, очень тесно связана с ней, так как отражает структуру
1.1.3. Дескрипторы вместо классов
1.1.3. Дескрипторы вместо классов Программируя в Delphi, мы быстро привыкаем к тому, что каждый объект реализуется экземпляром соответствующего класса. Например, кнопка реализуется экземпляром класса TButton, контекст устройства — классом TCanvas. Но когда создавались первые
Файловые менеджеры
Файловые менеджеры На протяжении всей книги уже не раз упоминалось о двух популярных файловых менеджерах – Konqueror из KDE и Nautilus из GNOME. Пользователям, работающим в консоли, можно предложить Midnight Commander (пакет mc). Две панели сине-белого цвета со строкой меню, расположенной
7.2.5. Дескрипторы файлов процесса
7.2.5. Дескрипторы файлов процесса Элемент fd файловой системы /proc — это подкаталог, в котором содержатся записи обо всех файлах, открытых процессом. Каждая запись представляет собой символическую ссылку на файл или устройство. Через эти ссылки можно осуществлять чтение и
6.5. Файловые структуры
6.5. Файловые структуры Файловая структура может быть одно– или многоуровневой. В одноуровневой структуре на носителе информации имена файлов образуют линейную последовательность, в многоуровневой, или иерархической, – древовидную структуру. Примером такой структуры
6.6. Файловые системы
6.6. Файловые системы 6.6.1. Назначение и функционирование файловой системы В операционных системах файловая система относится к основным понятиям и определяется как общая система, которая устанавливает правила присвоения имен файлам, хранение, организацию и обработку
Источник
Файл дескриптор в Linux с примерами
Однажды, на одном интервью меня спросили, что ты будешь делать, если обнаружишь неработающий сервис из-за того, что на диске закончилось место?
Конечно же я ответил, что посмотрю, чем занято это место и если возможно, то почищу место.
Тогда интервьюер спросил, а что если на разделе нет свободного места, но и файлов, которые бы занимали все место, ты тоже не видишь?
На это я сказал, что всегда можно посмотреть открытые файл дескрипторы, например командой lsof и понять какое приложение заняло все доступное место, а дальше можно действовать по обстоятельствам, в зависимости от того, нужны ли данные.
Интервьюер прервал меня на последнем слове, дополнив свой вопрос: «Предположим, что данные нам не нужны, это просто дебаг лог, но приложение не работает из-за того, что не может записать дебаг»?
«окей», — ответил я, «мы можем выключить дебаг в конфиге приложения и перезапустить его».
Интервьюер возразил: «Нет, приложение мы перезапустить не можем, у нас в памяти все еще хранятся важные данные, а к самому сервису подключены важные клиенты, которых мы не можем заставлять переподключаться заново».
«ну хорошо», сказал я, «если мы не можем перезапускать приложение и данные нам не важны, то мы можем просто очистить этот открытый файл через файл дескриптор, даже если мы его не видим в команде ls на файловой системе».
Интервьюер остался доволен, а я нет.
Тогда я подумал, почему человек, проверяющий мои знания, не копает глубже? А что, если данные все-таки важны? Что если мы не можем перезапускать процесс, и при этом этот процесс пишет на файловую систему в раздел, на котором нет свободного места? Что если мы не можем потерять не только уже записанные данные, но и те данные, что этот процесс пишет или пытается записать?
Тузик
В начале моей карьеры я пытался создать небольшое приложение, в котором нужно было хранить информацию о пользователях. И тогда я думал, а как мне сопоставить пользователя к его данным. Есть, например, у меня Иванов Иван Иваныч, и есть у него какие-то данные, но как их подружить? Я могу указать напрямую, что собака по имени «Тузик» принадлежит этому самому Ивану. Но что, если он сменит имя и вместо Ивана станет, например, Олей? Тогда получится, что наша Оля Ивановна Иванова больше не будет иметь собаки, а наш Тузик все еще будет принадлежать несуществующему Ивану. Решить эту проблему помогла база данных, которая каждому пользователю давала уникальный идентификатор (ID), и мой Тузик привязывался к этому ID, который, по сути, был просто порядковым номером. Таким образом хозяин у тузика был с ID под номером 2, и на какой-то момент времени под этим ID был Иван, а потом под этим же ID стала Оля. Проблема человечества и животноводства была практически решена.
Файл дескриптор
Проблема файла и программы, работающей с этим файлом, примерно такая же как нашей собаки и человека. Предположим я открыл файл под именем ivan.txt и начал в него записывать слово tuzik, но успел записать только первую букву «t» в файл, и этот файл был кем-то переименован, например в olya.txt. Но файл остался тем же самым, и я все еще хочу записать в него своего тузика. Каждый раз при открытии файла системным вызовом open в любом языке программирования я получаю уникальный ID, который указывает мне на файл, этот ID и есть файл дескриптор. И совершенно не важно, что и кто делает с этим файлом дальше, его могут удалить, его могут переименовать, ему могут поменять владельца или забрать права на чтение и запись, я все равно буду иметь к нему доступ, потому что на момент открытия файла у меня были права для его чтения и/или записи и я успел начать с ним работать, а значит должен продолжать это делать.
В Linux библиотека libc открывает для каждого запущенного приложения(процесса) 3 файл дескриптора, с номерами 0,1,2. Больше информации вы можете найти по ссылкам man stdio и man stdout
- Файл дескриптор 0 называется STDIN и ассоциируется с вводом данных у приложения
- Файл дескриптор 1 называется STDOUT и используется приложениями для вывода данных, например командами print
- Файл дескриптор 2 называется STDERR и используется приложениями для вывода данных, сообщающих об ошибке
Если в вашей программе вы откроете какой-либо файл на чтение или запись, то скорее всего вы получите первый свободный ID и это будет номер 3.
Список файл дескрипторов можно посмотреть у любого процесса, если вы знаете его PID.
Например, откроем консоль с bash и посмотрим PID нашего процесса
Во второй консоли запустим
Файл дескриптор с номером 255 можете смело игнорировать в рамках данной статьи, он был открыт для своих нужд уже самим bash, а не прилинкованной библиотекой.
Сейчас все 3 файл дескриптора связаны с устройством псевдотерминала /dev/pts, но мы все равно можем ими манипулировать, например запустим во второй консоли
И в первой консоли мы увидим
Redirect и Pipe
Вы можете легко переопределить эти 3 файл дескриптора в любом процессе, в том числе и в bash, например через трубу(pipe), соединяющую два процесса, смотрим
Вы можете сами запустить эту команду с strace -f и увидеть, что происходит внутри, но я вкратце расскажу.
Наш родительский процесс bash с PID 15771 парсит нашу команду и понимает сколько именно команд мы хотим запустить, в нашем случае их две: cat и sleep. Bash знает что ему нужно создать два дочерних процесса, и объединить их одной трубой. Итого bash потребуется 2 дочерних процесса и один pipe.
Перед созданием дочерних процессов bash запускает системный вызов pipe и получает новые файл дескрипторы на временный буфер pipe, но этот буфер никак пока не связывает наши два дочерних процесса.
Для родительского процесса это выглядит так будто pipe уже есть, а дочерних процессов еще нет:
Затем с помощью системного вызова clone bash создает два дочерних процесса, и наши три процесса будут выглядеть так:
Не забываем, что clone клонирует процесс вместе со всеми файл дескрипторами, поэтому в родительском процессе и в дочерних они будут одинаковые. Задача родительского процесса с PID 15771 следить за дочерними процессами, поэтому он просто ждет ответ от дочерних.
Следовательно pipe ему не нужен, и он закрывает файл дескрипторы с номерами 3 и 4.
В первом дочернем процессе bash с PID 9004, системным вызовом dup2, меняет наш STDOUT файл дескриптор с номером 1 на файл дескриптор указывающий на pipe, в нашем случае это номер 3. Таким образом все, что первый дочерний процесс с PID 9004 будет писать в STDOUT, будет автоматически попадать в буфер pipe.
Во втором дочернем процессе с PID 9005 bash меняет с помощью dup2 файл дескриптор STDIN с номером 0. Теперь все, что будет читать наш второй bash с PID 9005, будет читать из pipe.
После этого в дочерних процессах так же закрываются файл дескрипторы с номерами 3 и 4, так как они более не используются.
Файл дескриптор 255 я намеренно игнорирую, он использует для внутренних нужд самого bash и в дочерних процессах будет также закрыт.
Далее в первом дочернем процессе с PID 9004 bash запускает с помощью системного вызова exec исполняемый файл, который мы указали в командной строке, в нашем случае это /usr/bin/cat.
Во втором дочернем процессе с PID 9005 bash запускает второй исполняемый файл, который мы указали, в нашем случае это /usr/bin/sleep.
Системный вызов exec не закрывает файл дескрипторы, если они не были открыты с флагом O_CLOEXEC во время выполнения вызова open. В нашем случае после запуска исполняемых файлов все текущие файл дескрипторы сохранятся.
Проверяем в консоли:
Как видите уникальный номер нашего pipe у нас в обоих процессах совпадает. Таким образом у нас есть связь между двумя разными процессами с одним родителем.
Для тех, кто не знаком с системными вызовами, которые использует bash, крайне рекомендую запустить команды через strace и посмотреть, что происходит внутри, например, так:
Вернемся к нашей проблеме с нехваткой места на диске и попыткой сохранить данные без перезапуска процесса. Напишем небольшую программу, которая будет записывать на диск примерно 1 мегабайт в секунду. При этом если по какой-либо причине мы не смогли записать данные на диск, мы будем просто игнорировать это и пытаться записать данные вновь через секунду. В примере я использую Python, вы можете использовать любой другой язык программирования.
Запустим программу и посмотрим на файл дескрипторы
Как видим у нас есть наши 3 стандартные файл дескрипторы и еще один, который мы открыли. Проверим размер файла:
данные пишутся, пробуем поменять права на файл:
Видим, что данные все еще пишутся, хотя наш пользователь не имеет права писать в файл. Попробуем его удалить:
Куда пишутся данные? И пишутся ли вообще? Проверяем:
Да, наш файл дескриптор все еще существует, и мы можем работать с этим файл дескриптором как с нашим старым файлом, мы можем его читать, очищать и копировать.
Смотрим на размер файла:
Размер файла 19923457. Пробуем очистить файл:
Как видим размер файла только увеличивается и наш транкейт не сработал. Обратимся к документации по системному вызову open. Если при открытии файла мы используем флаг O_APPEND, то при каждой записи операционная система проверяет размер файла и пишет данные в самый конец файла, причем делает это атомарно. Это позволяет нескольким тредам или процессам писать в один и тот же файл. Но в нашем коде мы не используем этот флаг. Мы можем увидеть другой размер файла в lsof после транкейт только если откроем файл для дозаписи, а значит в нашем коде вместо
мы должны поставить
Проверяем с «w» флагом
Программируем уже запущенный процесс
Часто программисты при создании и тестировании программы используют дебагеры (например GDB) или различные уровни логирования в приложении. Linux предоставляет возможность фактически писать и менять уже запущенную программу, например менять значения переменных, устанавливать breakpoint и тд и тп.
Возвращаясь к оригинальному вопросу с нехваткой места на диске для записи файла, попробуем сэмулировать проблему.
Создадим файл для нашего раздела, который мы подмонтируем как отдельный диск:
Создадим файловую систему:
Подмонтируем файловую систему:
Создаем директорию с нашим владельцем:
Откроем файл только на запись в нашей программе:
Ждем несколько секунд
Итак, мы получили проблему, описанную в начале этой статьи. Свободного места 0, занятого 100%.
Мы помним, что по условиям задачи мы пытаемся записать очень важные данные, которые нельзя потерять. И при этом нам нужно починить сервис без перезапуска процесса.
Допустим, у нас все же есть место на диске, но в другом разделе, например в /home.
Попробуем «перепрограммировать на лету» наш код.
Смотрим PID нашего процесса, который съел все место на диске:
Подключаемся к процессу через gdb
Смотрим открытые файл дескрипторы:
Смотрим информацию о файл дескрипторе с номером 3, который нас интересует
Помня о том, какой системный вызов делает Python (смотрите выше, где мы запускали strace и находили вызов open), обрабатывая наш код для открытия файла, мы делаем то же самое самостоятельно от имени нашего процесса, но биты O_WRONLY|O_CREAT|O_TRUNC нам нужно заменить на числовое значение. Для этого открываем исходники ядра, например тут и смотрим какие флаги за что отвечают
#define O_WRONLY 00000001
#define O_CREAT 00000100
#define O_TRUNC 00001000
Объединяем все значения в одно, получаем 00001101
Запускаем наш вызов из gdb
Итак мы получили новый файл дескриптор с номером 4 и новый открытый файл на другом разделе, проверяем:
Мы помним пример с pipe — как bash меняет файл дескрипторы, и уже выучили системный вызов dup2.
Пробуем подменить один файл дескриптор другим
Закрываем файл дескриптор 4, так как нам он не нужен:
И выходим из gdb
Проверяем новый файл:
Как видим, данные пишутся в новый файл, проверяем старый:
Данные не потеряны, приложение работает, логи пишутся в новое место.
Немного усложним задачу
Представим, что данные нам важны, но места на диске у нас нет ни в одном из разделов и подключить диск мы не можем.
Что мы можем сделать, так это перенаправить куда-то наши данные, например в pipe, а данные из pipe в свою очередь перенаправить в сеть через какую-либо программу, например netcat.
Мы можем создать именованный pipe командой mkfifo. Она создаст псевдофайл на файловой системе, даже если на ней нет свободного места.
Перезапускаем приложение, и проверяем:
Места на диске нет, но мы успешно создаем там именованный pipe:
Теперь нам надо как-то завернуть все данные, что попадают в этот pipe на другой сервер через сеть, для этого подойдет все тот же netcat.
На сервере remote-server.example.com запускаем
На нашем проблемном сервере запускаем в отдельном терминале
Теперь все данные, которые попадут в pipe автоматически попадут на stdin в netcat, который их отправит в сеть на порт 7777.
Все что нам осталось сделать это начать писать наши данные в этот именованный pipe.
У нас уже есть запущенное приложение:
Из всех флагов нам нужен только O_WRONLY так как файл уже существует и очищать нам его не нужно
Проверяем удаленный сервер remote-server.example.com
Данные идут, проверяем проблемный сервер
Данные сохранились, проблема решена.
Пользуясь случаем, передаю привет коллегам из компании Degiro.
Слушайте подкасты Радио-Т.
В качестве домашнего задания предлагаю подумать, что будет в файл дескрипторах процесса cat и sleep если запустить такую команду:
Источник