Bash
Замена процесса
Поиск…
замечания
Подстановка процесса - это форма перенаправления, когда вход или выход процесса (некоторая последовательность команд) отображаются как временный файл.
Сравните два файла из Интернета
Ниже сравниваются два файла с diff
использующие замену процессов вместо создания временных файлов.
diff <(curl http://www.example.com/page1) <(curl http://www.example.com/page2)
Подайте цикл while с выходом команды
Это питает while
цикл с выходом grep
команды:
while IFS=":" read -r user _
do
# "$user" holds the username in /etc/passwd
done < <(grep "hello" /etc/passwd)
С помощью команды paste
# Process substitution with paste command is common
# To compare the contents of two directories
paste <( ls /path/to/directory1 ) <( ls /path/to/directory1 )
Объединение файлов
Хорошо известно, что вы не можете использовать тот же файл для ввода и вывода в той же команде. Например,
$ cat header.txt body.txt >body.txt
не делает то, что вы хотите. К моменту, когда cat
считывает body.txt
, он уже усечен перенаправлением и пуст. Конечным результатом будет то, что body.txt
будет содержать только содержимое header.txt
.
Можно подумать, чтобы избежать этого с заменой процесса, то есть, что команда
$ cat header.txt <(cat body.txt) > body.txt
заставит исходное содержимое body.txt
быть каким-то образом сохранено в некотором буфере где-то до того, как файл будет усечен перенаправлением. Это не работает. cat
в круглых скобках начинает читать файл только после того, как все дескрипторы файлов настроены, как и внешний. В этом случае нет смысла пытаться использовать замену процесса.
Единственный способ добавить файл к другому файлу - создать промежуточное:
$ cat header.txt body.txt >body.txt.new
$ mv body.txt.new body.txt
это то, что sed
или perl
или подобные программы выполняются под ковром при вызове с параметром edit-in-place (обычно -i
).
Поток файла через несколько программ одновременно
Это подсчитывает количество строк в большом файле с wc -l
, одновременно сжимая его с помощью gzip
. Оба запускаются одновременно.
tee >(wc -l >&2) < bigfile | gzip > bigfile.gz
Обычно tee
записывает свой ввод в один или несколько файлов (и stdout). Мы можем писать команды вместо файлов с tee >(command)
.
Здесь команда wc -l >&2
подсчитывает строки, считанные из tee
(которые, в свою очередь, bigfile
из bigfile
). (Счетчик строк отправляется на stderr ( >&2
), чтобы избежать смешивания с входом в gzip
.) Одновременное подавление tee
подается в gzip
.
Чтобы избежать использования суб-оболочки
Одним из основных аспектов замещения процесса является то, что он позволяет нам избегать использования под-оболочки при выполнении команд трубопровода из оболочки.
Это можно продемонстрировать с помощью простого примера ниже. У меня есть следующие файлы в моей текущей папке:
$ find . -maxdepth 1 -type f -print
foo bar zoo foobar foozoo barzoo
Если я подключаюсь к циклу while
/ read
который увеличивает счетчик следующим образом:
count=0
find . -maxdepth 1 -type f -print | while IFS= read -r _; do
((count++))
done
$count
now не содержит 6
, потому что он был изменен в контексте подкласса. Любая из приведенных ниже команд запускается в контексте под-оболочки, а область переменных, используемых внутри, теряется после завершения суб-оболочки.
command &
command | command
( command )
Замена процесса решит проблему, избегая использования трубы |
оператора в
count=0
while IFS= read -r _; do
((count++))
done < <(find . -maxdepth 1 -type f -print)
Это сохранит count
переменной count
как никакие под-оболочки не будут вызваны.