Ввод трубы в несколько процессов [zsh] - PullRequest
5 голосов
/ 14 февраля 2011

Я знаю о возможности для zsh:

ls -1 >foo >bar

Но, скажем, я хочу запустить оба выхода через другую команду.Например, как мне объединить эти две команды, чтобы избежать запуска mysqldump дважды?

mysqldump db1 | bzip2 > db1.sql.bz2
mysqldump db1 | mysql db2

Самое близкое, что я могу придумать:

mysqldump db1 >db1.sql | mysql db2
bzip2 db1.sql

Но я 'не хочу записывать файл на диск без сжатия (он большой!).

Ответы [ 3 ]

6 голосов
/ 14 февраля 2011

Вы можете использовать процесс подстановки.

В зш:

ls -1 > >(grep foo) > >(grep bar)

В Баш:

ls -1 | tee >(grep foo) >(grep bar) >/dev/null

Замена процесса управляет именованными каналами.

5 голосов
/ 14 февраля 2011

Работает следующее:

echo abc > >(gzip > 1) > >(xz > 2)

Изменено для вашего примера (но не проверено):

mysqldump db1 > >(bzip2 > db1.sql.bz2) > >(mysql db2)

или, возможно, лучше:

{ mysqldump db1 } > >(bzip2 > db1.sql.bz2) > >(mysql db2)

//Я нашел почти такой же пример в разделе ЗАМЕНА ПРОЦЕССА в man zshexpn:

Также обратите внимание, что предыдущий пример может быть записан более компактно и эффективно (при условии, что установлена ​​опция MULTIOS) как:

   paste <(cut -f1 file1) <(cut -f3 file2) \
   > >(process1) > >(process2)

Оболочка использует каналы вместо FIFO для реализации двух последних замен процесса в приведенном выше примере.

Существует дополнительная проблема с> (процесс);когда он присоединен к внешней команде, родительская оболочка не ожидает завершения процесса и, следовательно, сразу следующая команда не может полагаться на завершение результатов.Проблема и решение те же, что описаны в разделе MULTIOS в zshmisc (1).Следовательно, в упрощенной версии приведенного выше примера:

   paste <(cut -f1 file1) <(cut -f3 file2) > >(process)

(обратите внимание, что MULTIOS не задействованы), процесс будет выполняться асинхронно.Обходной путь:

   { paste <(cut -f1 file1) <(cut -f3 file2) } > >(process)

Дополнительные процессы здесь порождаются из родительской оболочки, которая будет ожидать их завершения.

1 голос
/ 14 февраля 2011

Вы можете подключать процессы через fifo и использовать утилиту tee для копирования стандартного вывода в каждое fifo и stdout.Что-то вроде:

mkfifo db1.sql
bzip2 db1.sql &
mysqldump db1 | tee db1.sql | mysql db2
...