Вы, наверное, уже знакомы с вводом/выводом и перенаправлением каналов в Linux.
Позвольте нам рассказать вам о похожей, но продвинутой функции, называемой подстановкой процесса.
Вы найдете два вида синтаксиса для замены процесса:
<(commands)
или
>(commands)
Позвольте нам остановиться немного подробнее.
Вы обнаружите, что замена процесса может использоваться аналогично перенаправлению STDOUT или STDIN.
Оператором С <(commands) вы читаете замену. Это означает, что commands настроена на использование как stdout.
Например, следующая команда использует вывод ls *sh:
wc -l <(ls *sh)
Это эквивалентно:
ls *sh | wc -l
Оператором С >(commands) вы пишете на замену. Это означает, что commands настроена на использование как stdin.
Другими словами, когда у вас есть команда, которая выводит данные в файл, но вы хотите, чтобы она записывалась в какую-то другую команду вместо файла.
Вот пример, который должен прояснить ситуацию:
tar -cf >(ssh remote_server tar xf -).
Вы понимаете, что она делает? Вы только что перенесли все содержимое текущего каталога на удаленный сервер. Файл архива создается на лету и распаковывается на сервере.
Если честно, оператор >(…) встречается реже. Вы обнаружите, что <(…) можно использовать чаще.
Итак, в чем преимущество подстановки процессов, если она работает как обычное перенаправление ввода-вывода?
Вы поймете силу и полезность подстановки процессов bash, когда у вас есть несколько командных конвейеров, которые можно объединить в одну команду.
Наиболее очевидное и наиболее частое использование подмены процесса — это сравнение результатов двух программ. Позвольте показать вам это на практическом примере.
Допустим, у вас есть файлы программы C и соответствующие им объектные файлы (файл .out) с тем же именем в каталоге.
ls * aa.c aa.out bb.c bb.out cc.c cc.out ...
Вот ваша цель. Вы хотите проверить, имеет ли каждый файл C соответствующий выходной файл с тем же именем, что и файл C.
Ваш типичный подход — перечислить файлы, отфильтрованные по расширению, а затем использовать команду cut с разделителем. (Точка), чтобы извлечь имя файла без расширения:
ls *.c | cut -d. -f1 aa bb cc dd
Ваш типичный подход — сохранить вывод файлов * .c и * .out во временные файлы, а затем сравнить эти файлы с помощью команды diff . Мы правы?
ls *.c | cut -d. -f1 > c.txt ls *.out | cut -d. -f1 > out.txt diff c.txt out.txt rm c.txt out.txt
Вы можете использовать каталог /tmp для создания временных файлов, но у вас все еще есть три строки команд.
Вы можете красиво использовать подстановку процесса, чтобы заменить все вышеперечисленное одной командой без создания временных файлов:
diff <(ls *.c | cut -d. -f1) <(ls *.out | cut -d. -f1)
Вам не нужно было создавать здесь какие-либо временные файлы, и это главное. Вот наш совет о том, когда следует использовать замену процесса.
Каждый раз, когда вы думаете, что вам нужен временный файл для чего-то, подумайте, можно ли использовать замену процесса.
Замена процесса является функцией bash и может работать или не работать с другой оболочкой.
Мы надеемся, что вы попытаетесь использовать замену процесса в будущем. Как видите, это весьма полезно. Ждем ваших вопросов и предложений.