Данные не обязательно хранить в оперативной памяти. Пайпы блокируют своих авторов, если читателей нет или они не успевают за ними; в Linux (и большинстве других реализаций, я полагаю, )есть некоторая буферизация, но она не требуется. Как упоминалось mtraceur и JdeBP (, см. ответ последнего ), ранние версии Unix буферизовали каналы на диск, и именно так они помогли ограничить использование памяти :. конвейер обработки может быть разбит на небольшие программы, каждая из которых будет обрабатывать некоторые данные в пределах дисковых буферов. Небольшие программы занимают меньше памяти, а использование конвейеров означало, что обработка может быть сериализована :: первая программа будет запускаться, заполнять свой выходной буфер, приостанавливаться, затем будет планироваться вторая программа, обрабатывать буфер и т. д. Современные системы на порядки больше, чем ранние системы Unix, и могут запускать множество каналов параллельно; но для огромных объемов данных вы все равно увидите аналогичный эффект (, и варианты этого метода используются для обработки «больших данных» ).
В вашем примере
sed 'simplesubstitution' file | sort | uniq > file2
sed
считывает данные из file
по мере необходимости, затем записывает их до тех пор, пока sort
готов их прочитать; если sort
не готов, запись блокируется. Данные действительно остаются в памяти в конечном итоге, но это характерно для sort
, и sort
готов решать любые проблемы (, он будет использовать временные файлы, если количество данных для сортировки слишком велико ).
Вы можете увидеть поведение блокировки, запустив
strace seq 1000000 -1 1 | (sleep 120; sort -n)
Это производит достаточное количество данных и направляет их процессу, который не готов что-либо читать в течение первых двух минут. Вы увидите, как выполняется ряд write
операций,но очень быстро seq
остановится и будет ждать две минуты, заблокированные ядром (системный вызов write
ждет ).