i have a bash script, that has the following two commands:
ssh host tail -f /some/file | awk ..... > /some/file &
ssh host tail -f /some/file | grep
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.
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
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.