- What are Named Pipes or FIFO in Linux/Unix systems?
- Two-way Communication Using Named Pipes
- Pipes: Программные каналы в Linux
- Статья из цикла HuMan
- Выбор термина
- Предисловие
- Введение в программные каналы
- Как это работает
- Как пользоваться программными каналами
- Другие распространенные команды-фильтры
- Сложные программные каналы
- Немного истории
- Понятие именованного канала
What are Named Pipes or FIFO in Linux/Unix systems?
Pipes were meant for communication between related processes. We Cannot use pipes for unrelated process communication. Then to achieve unrelated processes communication, the simple answer is Named Pipes. Even though this works for related processes, it gives no meaning to use the named pipes for related process communication.
Unlike pipe, we can use single named pipe that can be used for two-way communication (communication between the server and the client, plus the client and the server at the same time) as Named Pipe supports bi-directional communication.
Another name for named pipe is FIFO (First-In-First-Out). Let us see the system call (mknod()) to create a named pipe, which is a kind of a special file.
This system call would create a special file or file system node such as ordinary file, device file, or FIFO. The arguments to the system call are pathname, mode and dev. The pathname along with the attributes of mode and device information. The pathname is relative, if the directory is not specified it would be created in the current directory. The mode specified is the mode of file which specifies the file type such as the type of file and the file mode as mentioned in the following tables. The dev field is to specify device information such as major and minor device numbers.
File Type | Description | File Type | Description |
---|---|---|---|
S_IFBLK | block special | S_IFREG | Regular file |
S_IFCHR | character special | S_IFDIR | Directory |
S_IFIFO | FIFO special | S_IFLNK | Symbolic Link |
File Mode | Description | File Mode | Description |
---|---|---|---|
S_IRWXU | Read, write, execute/search by owner | S_IWGRP | Write permission, group |
S_IRUSR | Read permission,owler | S_IXGRP | Execute/search permission, group |
S_IWUSR | Write permission, owner | S_IRWXO | Execute/search permission, group |
S_IXUSR | Execute/search permission, owner | S_IROTH | Read permission, others |
S_IRWXG | Read, write, execute/search by group | S_IWOTH | Write permission, others |
S_IRGRP | Read permission, group | S_IXOTH | Execute/search permission, others |
File mode can also be represented in octal notation such as 0XYZ, where X represents owner, Y represents group, and Z represents others. The value of X, Y or Z can range from 0 to 7. The values for read, write and execute are 4, 2, 1 respectively. If needed in combination of read, write and execute, then add the values accordingly.
Say, if, 0640, then this means read and write (4 + 2 = 6) for owner, read (4) for group and no permissions (0) for others.
This call would return zero on success and -1 in case of failure. To know the cause of failure, check with errno variable or perror() function.
This library function creates a FIFO special file, which is used for named pipe. The arguments to this function is file name and mode. The file name can be either absolute path or relative path. If full path name (or absolute path) is not given, the file would be created in the current folder of the executing process. The file mode information is as described in mknod() system call.
This call would return zero on success and -1 in case of failure. To know the cause of failure, check with errno variable or perror() function.
Let us consider a program of running the server on one terminal and running the client on another terminal. The program would only perform one-way communication. The client accepts the user input and sends the message to the server, the server prints the message on the output. The process is continued until the user enters the string “end”.
Let us understand this with an example −
Step 1 − Create two processes, one is fifoserver and another one is fifoclient.
Step 2 − Server process performs the following −
Creates a named pipe (using system call mknod()) with name “MYFIFO”, if not created.
Opens the named pipe for read only purposes.
Here, created FIFO with permissions of read and write for Owner. Read for Group and no permissions for Others.
Waits infinitely for message from the Client.
If the message received from the client is not “end”, prints the message. If the message is “end”, closes the fifo and ends the process.
Step 3 − Client process performs the following −
1) Opens the named pipe for write only purposes.
2) Accepts the string from the user.
3) Checks, if the user enters “end” or other than “end”. Either way, it sends a message to the server. However, if the string is “end”, this closes the FIFO and also ends the process.
4) Repeats infinitely until the user enters string “end”.
Two-way Communication Using Named Pipes
The communication between pipes are meant to be unidirectional. Pipes were restricted to one-way communication in general and need at least two pipes for two-way communication. Pipes are meant for inter-related processes only. Pipes can’t be used for unrelated processes communication, say, if we want to execute one process from one terminal and another process from another terminal, it is not possible with pipes. Named pipe is meant for communication between two or more unrelated processes and can also have bi-directional communication.
Already, we have seen the one-directional communication between named pipes, i.e., the messages from the client to the server. Now, let us take a look at the bi-directional communication i.e., the client sending message to the server and the server receiving the message and sending back another message to the client using the same named pipe.
Following is an example −
Step 1 − Create two processes, one is fifoserver_twoway and another one is fifoclient_twoway.
Step 2 − Server process performs the following −
Creates a named pipe (using library function mkfifo()) with name “fifo_twoway” in /tmp directory, if not created.
Opens the named pipe for read and write purposes.
Here, created FIFO with permissions of read and write for Owner. Read for Group and no permissions for Others.
Waits infinitely for a message from the client.
If the message received from the client is not “end”, prints the message and reverses the string. The reversed string is sent back to the client. If the message is “end”, closes the fifo and ends the process.
Step 3 − Client process performs the following −
Opens the named pipe for read and write purposes.
Accepts string from the user.
Checks, if the user enters “end” or other than “end”. Either way, it sends a message to the server. However, if the string is “end”, this closes the FIFO and also ends the process.
If the message is sent as not “end”, it waits for the message (reversed string) from the client and prints the reversed string.
Repeats infinitely until the user enters the string “end”.
Источник
Pipes: Программные каналы в Linux
Статья из цикла HuMan
Выбор термина
Какие только термины не используют в русском языке для перевода слова «pipes»: и трубы, и трубопроводы, и конвейеры, и потоки, и прочее. В контексте все эти термины выглядят довольно неуклюже. И вот еще беда — ни от одного из этих существительных нельзя образовать глагол, не говоря уже о том, чтобы называть так символ вертикальной черты. Можно, правда, употребить глагол «конвейеризировать», но такое не написать, не выговорить невозможно. Я пытался делать наметки этой статьи, используя все перечисленные термины, но не был удовлетворен ни одним.
Совершенно случайно, в книге А. Робачевского «Операционная система UNIX» мне встретился термин «программные каналы». Поначалу он показался мне несколько громоздким, но попробовав его на деле, я убедился в его несомненных преимуществах. Он не выглядит смешно и дико как «трубы», от него легко произвести глагол, и, самое главное, он имеет вполне прижившегося на русской почве брата — «именованные каналы», которые никто не назовет «именованными трубопроводами». Итак, решено, в данной статье термин pipes будет звучать как «программные каналы».
Предисловие
Предлагаемая вашему вниманию статья как раз для тех, кто недавно открыл для себя командную строку Линукс.
Введение в программные каналы
Команда dmesg выводит сообщения ядра Линукс о процессе загрузки ОС (те самые, что пробегают по экрану монитора при загрузке системы). Эти сообщения не умещаются на одном экране, и пролетают так быстро, что прочесть их невозможно. Поэтому вывод программы dmesg передают на ввод команде less. (Команда less позволяет выводу команды dmesg заполнить только один экран. Чтобы прочесть следующую порцию текста, нужно нажать клавишу пробела, а чтобы вернуться к предыдущей порции — клавишу b. Прервать работу программы можно клавишей q). Оператором такой передачи служит вертикальная черта (|). (Пробелы до и после вертикальной черты ставятся для удобства чтения, но можно обойтись и без них). Все вместе и есть простейший программный канал.
Того же результата можно достичь, если сначала перенаправить вывод команды dmesg во временный файл, а затем просмотреть содержимое этого файла на экране монитора.
Очевидно, что такая схема менее производительна: во-первых, необходимо давать две команды, во-вторых потому, что следующая команда может начать работать только после завершения первой.
Необходимо пояснить понятия, которые я походя назвал «вводом» и «выводом» программы.
Любая программа командной оболочки (шелла) оперирует с тремя потоками данных: стандартным вводом (stdin), стандартным выводом (stdout), и стандартным сообщением об ошибке (stderr). (Подробно об этом можно прочесть в статье «Перенаправление стандартных потоков данных»).
По умолчанию, стандартный ввод осуществляется с клавиатуры, а стандартный вывод — на экран монитора. Если же мы задействуем оператор программных каналов (|), то стандартный вывод первой программы станет стандартным вводом второй, при этом на экране монитора он уже не появится.
Такая цепочка вовсе не ограничивается двумя программами, но может продолжаться сколь угодно долго.
Как это работает
Даже если посылающая программа производит 5000 байт в секунду, а принимающая программа может обработать только 100 байт в секунду, все равно никакой потери информации не произойдет, так как программные каналы имеют буферы. Вывод посылающей программы собирается в буфере, ставится в очередь. Когда принимающая программа готова считывать данные, операционная система посылает порцию данных из буфера. В случае переполнения буфера, посылающая программа приостанавливается (блокируется), до тех пор, пока принимающая программа не сможет снова считывать данные, тем самым освобождая буфер.
Механизм этого свойства командной оболочки довольно сложен, в данной статье мы не станем его рассматривать, а будем просто пользоваться этой замечательной способностью шелла.
Как пользоваться программными каналами
Кроме вышеприведенного примера с каналом dmesg | less , часто используется канал ls | less . Команда ls позволяет просматривать содержимое директорий, а с опцией -l дает подробные сведения о файлах, «населяющих» указанную директорию. Если директория содержит достаточно файлов, чтобы их список занял больше одного экрана, то применение программного канала с less или more неизбежно:
Для пробы проделайте такой пример:
Только запаситесь терпением — на моей небольшой системе, установленной с одного CD, в выводе было 87 187 строк, сиречь файлов. Дело в том, что опция -R команды ls выводит содержимое директории рекурсивно, то есть открывая подкаталоги, подкаталоги подкаталогов и так далее, пока не перечислит все файлы. Правда, чтобы просмотреть действительно все файлы в директории, нужно войти как администратор (root), потому что некоторые каталоги могут не давать прав доступа рядовому пользователю.
Понятно, что найти «вручную» что-либо в таком списке проблематично, и тут на помощь снова придут программные каналы.
Команда grep найдет нужные вам строки, если вы зададите образец для поиска:
Обратите внимание на символ # в начале командной строки — он означает, что я вошел с правами суперпользователя.
Команды, входящие в состав программных каналов, часто называются командами-фильтрами, так как они пропускают через себя потоки данных.
Среди команд-фильтров самая употребительная, без сомнения, grep. Она применяется везде, где нужно выбрать искомое из большого объема данных. Скажем, просмотреть все, что касается USB в выводе команды dmesg:
Это только начало списка строк, выведенных командой grep -i usb , я не привожу его полностью из экономии места. Опция -i приказывает команде grep не замечать разницы между заглавными и строчными буквами.
Любой системный администратор часто пользуется командой ps. С опциями -e и -f она выводит все процессы, текущие в системе в полной форме (подробно). Процессов этих весьма много, поэтому я не привожу полный вывод команды:
Чтобы найти в этом списке интересующие вас процессы, следует канализировать команду ps с командой grep. Допустим, вас интересуют процессы hald:
С таким коротким списком уже легче работать. (Обратите внимание на последнюю строчку, там представлен сам запущенный нами процесс grep hald ).
Другие распространенные команды-фильтры
sort — сортирует строки по алфавиту или порядку номеров
wc — подсчитывает количество строк, слов, байт или символов в тексте
tr — заменяет одни символы другими
sed — позволяет редактировать текст прямо из командной строки, даже не видя его.
cut — вырезает из текста нужные куски и выдает их на стандартный вывод
head/tail — позволяют ограничить просмотр первыми несколькими строками (head — голова), либо последними несколькими строками (tail — хвост).
В этот список я включил только несколько команд-фильтров, освоив которые, можно вдоволь насладиться составлением самых замысловатых программных каналов.
Сложные программные каналы
Примечание: Символ (\) используется для объединения всех шести строк в одну командную строку.
Команда первая: wget получает содержимое HTML web страницы.
Команда вторая: sed удаляет из текста страницы все символы, не являющиеся пробелами или буквами и заменяет их пробелами.
Команда третья: tr переводит все символы верхнего регистра в нижний регистр (заглавные буквы в строчные), а также конвертирует пробелы в строках в символы новой строки, так что теперь каждое «слово» является новой строкой.
Команда четвертая: grep оставляет только строки, содержащие хотя бы один алфавитный символ (попросту букву), удаляя все пустые строки.
Команда пятая: sort сортирует список «слов» в алфавитном порядке, а с опцией -u удаляет дубликаты.
Команда шестая, и последняя: comm находит строки, общие для двух файлов. Первым файлом является стандартный вывод нашего программного канала, для чего вместо имени первого файла стоит прочерк (-), вторым файлом будет файл words.txt. Строки, которые встречаются только во втором файле и те, что встречаются в обоих файлах, подавляются опциями -2 и -3. Результатом будет список слов, встречающихся только в первом файле. И, если считать файл words.txt неким эталонным словарем, то выходящий список будет содержать слова, которых нет в словаре, то есть написанные с ошибками.
Немного истории
Понятие именованного канала
В отличие от анонимного программного канала, автоматически создаваемого шеллом, именованный канал обладает именем, и создается явно при помощи команд mknod или mkfifo. Создадим именованный канал fifo1:
Теперь запустим процесс, обращающийся к данному каналу:
Несмотря на нажатие клавиши ENTER ничего не происходит, что не удивительно, ведь файл fifo1 пока пуст, и команде grep нечего обрабатывать. Однако консоль оказывается занята ждущим процессом, и разблокировать ее можно только прервав процесс (скажем, нажатием клавиш CTRL+c).
Чтобы наполнить именной канал содержимым, нужно чтобы к нему обратился второй процесс. Для этого мы должны открыть вторую консоль и запустить какую-либо команду, передающую данные в файл fifo1. Например:
Немедленно в первой консоли сработает команда grep:
Совершенно ясно, что пользоваться таким неудобным механизмом в пользовательских целях никто не будет, ведь гораздо проще запустить один программный канал:
и получить тот же результат.
Этот пример я привел лишь для демонстрации создания и работы именованного канала. Другое дело, когда именованные каналы создаются самими процессами для обмена информацией друг с другом. Но повторюсь, что тема эта непростая и в данной статье рассматриваться не будет.
Источник