user2864207
user2864207

Reputation: 353

How to redirect output of multiple commands to one file?

I have a bash script that contains the following two commands:

ssh host tail -f /some/file | awk ..... > /some/file &

ssh host tail -f /some/file | grep .... > /some/file &

How can I make the output of both commands be directed into the same file?

Upvotes: 25

Views: 44522

Answers (3)

Jonathan Leffler
Jonathan Leffler

Reputation: 754570

Either use 'append' with >> or use braces to encompass the I/O redirections, or (occasionally) use exec:

ssh host tail -f /some/file | awk ..... >  /some/file &
ssh host tail -f /some/file | grep .... >> /some/file &

or:

{
ssh host tail -f /some/file | awk ..... &
ssh host tail -f /some/file | grep .... &
} > /some/file

or:

exec > /some/file
ssh host tail -f /some/file | awk ..... &
ssh host tail -f /some/file | grep .... &

After the exec, the standard output of the script as a whole goes to /some/file. I seldom use this technique; I usually use the { ...; } technique instead.

Note: You do have to be careful with the braces notation. What I showed will work. Trying to flatten it onto one line requires you to treat the { as if it were a command (followed by a space, for example) and also to treat the } as if it were a command. You must have a command terminator before the } — I used a newline, but an & for background or ; would work too.

Thus:

{ command1;  command2;  } >/some/file
{ command1 & command2 & } >/some/file

I also have not addressed the issue of why you have two separate tail -f operations running on a single remote file and why you are not using awk power as a super-grep to handle it all in one — I've only addressed the surface question of how to redirect the I/O of the two commands to one file.

Upvotes: 46

glenn jackman
glenn jackman

Reputation: 247042

Note you can reduce the number of ssh calls:

{  ssh host tail -f /some/file | 
     tee >(awk ...) >(grep ...) >/dev/null
} > /some/file &

example:

{ echo foobar | tee >(sed 's/foo/FOO/') >(sed 's/bar/BAR/') > /dev/null; } > outputfile
cat outputfile 
fooBAR
FOObar

Upvotes: 21

twalberg
twalberg

Reputation: 62459

The best answer to this is to probably get rid of the ssh .... | grep ... line, and modify the awk script in the other command to add the functionality you were getting from the grep command...

That will get rid of any interleaving issues as a bonus side-effect.

Upvotes: 2

Related Questions