The problem isn't with the redirection, it's with how you're storing the command in a variable. First, you can't put a space after the = in the assignment; with the space there, it sets CMD blank and runs the command mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'. If you just remove the space, it'll set CMD to "mysql" and try to run the command -uroot -psecret -e 'SHOW SLAVE STATUS \G;'. So, as @Michał Šrajer suggested, you could wrap it in double-quotes so the whole thing gets assigned to CMD. But it still doesn't work, because when $CMD is expanded, it doesn't pay attention to the quotes inside it. When bash parses a command line, it parses quotes before it expands variables, so putting quotes inside a variable doesn't do anything useful.
Storing a command in a variable is tricky. BashFAQ #50 has some good discussion and options. In this case, the options that look relevant to me are:
Don't put the command in a variable in the first place. If there's no good reason for it, don't do it:
FIL=~/replication-`date +%F`.txt
MAILTEXT=~/mailtext.txt
touch $FIL
mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;' > $FIL
If you must put the command in a variable, use an array instead of a simple text variable. In this case, the quotes will be parsed when the variable in created, and if you use it as "${varname[@]}" the breaks between "words" will be preserved:
CMD=(mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;')
FIL=~/replication-`date +%F`.txt
MAILTEXT=~/mailtext.txt
touch $FIL
"${CMD[@]}" > $FIL
CMDwill not work, get rid of the space after=and surround the values with double quotes -shis extremely odd in its treatment of whitespace. – reinierpost Sep 19 '11 at 16:15