Давайте повернемося назад до прикладу з каналами, оскільки він є досить цікавим, а також уявляє добру ілюстрацію для розуміння посилань. Коли ви в командному рядку використовуєте канал, shell створює для вас канал і працює так, що команда перед каналом виконує в нього запис, а команда після каналу виконує читання з нього. Усе канали, чи то анонімні (як ті, що використовуються в shell'ах), чи то іменовані (дивіться нижче), працюють відповідно до принципу простої черги FIFO (First In, First Out, “першим прийшов - першим обслуговано”). Ми вже бачили приклади використання каналів в shell'і, але погляньмо ще на один приклад для демонстрації цього принципу:
$ ls -d /proc/[0-9] | head -5 /proc/1/ /proc/2/ /proc/3/ /proc/4/ /proc/5/
Одна річ, яку ви не помітите в цьому прикладі (бо це відбувається занадто швидко), полягає в блокуванні запису в канали. Це означає, що коли команда ls виконує запис в канал, він блокується доти, доки процес виконує читання на іншому кінці. Щоб побачити цей ефект, ви можете створити іменовані канали, які, на відміну від каналів, використовуваних shell'ами, мають імена (тобто вони є пов'язаними, тоді як канали shell'а - ні)[5]. Команда для створення іменованого каналу - mkfifo:
$ mkfifo a_pipe
$ ls -il
total 0
169 prw-rw-r-- 1 queen queen 0 Aug 6 19:37 a_pipe|
#
#Ви можете бачити, що лічильник посилань дорівнює 1,
# а файл є каналом ('p').
#
# Ви також можете використовувати тут ln:
#
$ ln a_pipe the_same_pipe
$ ls -il
total 0
169 prw-rw-r-- 2 queen queen 0 Aug 6 19:37 a_pipe|
169 prw-rw-r-- 2 queen queen 0 Aug 6 19:37 the_same_pipe|
$ ls -d /proc/[0-9] >a_pipe
#
# Процес заблоковано, бо на іншому кінці немає програми читання.
# Натисніть Control Z, щоб призупинити процес...
#
[1]+ Stopped ls -F --show-control-chars --color=auto -d /proc/[0-9] >a_pipe
#
# ...Потім відправте його у фоновий режим:
#
$ bg
[1]+ ls -F --show-control-chars --color=auto -d /proc/[0-9] >a_pipe &
#
# тепер виконуємо читання з каналу...
#
$ head -5 <the_same_pipe
#
# ...процес запису завершено
#
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
[1]+ Done ls -F --show-control-chars --color=auto -d /proc/[0-9] >a_pipe
$Аналогічним чином читання теж блокується. Якщо ми виконаємо наведені вище команди у зворотному порядку, ми побачимо що команда head блокується, очікуючи, щоб якийсь процес дав їй щось прочитати:
$ head -5 <a_pipe # # Програму заблоковано, призупиніть її: C-z # [1]+ Stopped head -5 <a_pipe # # Відправляємо її в фоновий режим... # $ bg [1]+ head -5 <a_pipe & # # ...І даємо їй щось поїсти :) # $ ls -d /proc/[0-9] >the_same_pipe /proc/1/ /proc/2/ /proc/3/ /proc/4/ /proc/5/ [1]+ Done head -5 <a_pipe $
Ви також можете побачити небажаний ефект у попередньому прикладі: команду було ls завершено до того, як почала працювати команда head. У результаті ви негайно повернулися до запрошення в консолі, а head виконалася пізніше, і ви побачили її висновок тільки після повернення.