Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I `tee` output to multiple piped commands with zsh on macOS?

I am using the tmutil status command to give me the current TimeMachine backup status. It gives an output of the sort

% tmutil status
Backup session status:
{
    BackupPhase = Copying;
    ClientID = "com.apple.backupd";
    DateOfStateChange = "2022-11-21 11:23:03 +0000";
    DestinationID = "89E08126-7132-4D14-80B4-EFD45E8C5BFC";
    FirstBackup = 1;
    Progress =     {
        Percent = "0.1640944884974286";
        TimeRemaining = 65013;
        "_raw_Percent" = "0.1640944884974286";
        "_raw_totalBytes" = 488603537408;
        bytes = 80177147549;
        files = 159679;
        totalBytes = 488603537408;
        totalFiles = 3345928;
    };
    Running = 1;
    Stopping = 0;
}

This is not JSON, though it looks a bit like it.

I want to report on the Percent Complete and the Time Remaining.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I can get the Percent Complete with

tmutil status | grep "raw_Percent" | LC_NUMERIC="C" awk -F '"' '{print "Percent Complete: " ($4 * 100) "%"} '

and I can get the Time Remaining with

tmutil status | grep "TimeRemaining" | awk '{print "Time Remaining: " ($3/3600) " hours"} '

How can I run tmutil once (it seems to be a little expensive), and send the output to two grep ... | awk ... commands?

My understanding is that I could do

tmutil status | tee > (grep "raw_Percent" | LC_NUMERIC="C" awk -F '"' '{print "Percent Complete: " ($4 * 100) "%"} ') | (grep "TimeRemaining" | awk '{print "Time Remaining: " ($3/3600) " hours"} ')

with each command (pipes and all) in brackets.

But, instead, I get

zsh: no matches found: (grep raw_Percent | LC_NUMERIC=C awk -F " {print "Percent Complete: " ($4 * 100) "%"} )

>Solution :

You are trying to redirect the standard output of tee to a subshell. What you want are two separate process substitutions, tee >(...) >(...). (Note the lack of a space between > and ( in each case.)

As an aside, you don’t need to use grep in either case; just let awk filter the lines.

tmutil status | 
  tee >(LC_NUMERIC="C" awk -F '"' '/raw_Percent/ {print "Percent Complete: " ($4 * 100) "%"} ') \
      >(awk '/TimeRemaining/ {print "Time Remaining: " ($3/3600) " hours"} ')
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading