将标准输出同时传输到多个进程 [zsh]

7

我知道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个回答

7
以下内容是有效的:
echo abc > >(gzip > 1) > >(xz > 2)

针对您的示例进行修改(但未经测试):

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

或者,可能更好的方式:

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

今日免费次数已满, 请开通会员/明日再来

Also note that the previous example can be more compactly and efficiently written (provided the MULTIOS option is set) as:

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

The shell uses pipes instead of FIFOs to implement the latter two process substitutions in the above example.

There is an additional problem with >(process); when this is attached to an external command, the parent shell does not wait for process to finish and hence an immediately following command cannot rely on the results being complete. The problem and solution are the same as described in the section MULTIOS in zshmisc(1). Hence in a simplified version of the example above:

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

(note that no MULTIOS are involved), process will be run asynchronously. The workaround is:

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

The extra processes here are spawned from the parent shell which will wait for their completion.


7
您可以使用进程替换功能。
在zsh中:
ls -1 > >(grep foo) > >(grep bar)

在bash中:

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

进程替换为您管理命名管道。

+1 - 我接受了@ZyX的回答,因为它更完整地解决了等待命令完成的问题,但我喜欢在这里使用bash和tee的选项,因为我并不总是在zsh中。谢谢! - wuputah

1

你可以通过fifo连接进程,并使用tee实用程序将标准输出复制到每个fifo和stdout。类似这样:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接