I'm aware of the ability for zsh to do:
ls -1 >foo >bar
But let's say I want to run both outputs through another command. For instance, how would I combine these two commands so as to avoid running mysqldump
twice?
mysqldump db1 | bzip2 > db1.sql.bz2
mysqldump db1 | mysql db2
The closest I can come up with is:
mysqldump db1 >db1.sql | mysql db2
bzip2 db1.sql
But I'd rather not write the file to disk uncompressed (it's big!).
The following works:
echo abc > >(gzip > 1) > >(xz > 2)
Modified for your example (but untested):
mysqldump db1 > >(bzip2 > db1.sql.bz2) > >(mysql db2)
or, probably better:
{ mysqldump db1 } > >(bzip2 > db1.sql.bz2) > >(mysql db2)
// I found almost the same example in PROCESS SUBSTITUTION section in man zshexpn
:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With