Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

This seems so simple when doing it from command line but I'm not able to accomplish it inside a script. I am trying to put output of following command into a text file:

CMD= mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'
FIL=~/replication-`date +%F`.txt
MAILTEXT=~/mailtext.txt

touch $FIL
$CMD > $FIL

Where FIL is a variable that contains path of the file to which to output command. I am running this command in a shell script from where I want to email contents of $FIL as attachment using mutt. But I am always getting 0 byte file. Also if I examine in directory the file is of 0 byte length.

share|improve this question
    
what if you do (mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;') > $FILE –  barlop Sep 19 '11 at 15:34
    
@barlop I have updated question with actual script. –  TheVillageIdiot Sep 19 '11 at 15:37
    
Your first assignment to CMD will not work, get rid of the space after = and surround the values with double quotes - sh is extremely odd in its treatment of whitespace. –  reinierpost Sep 19 '11 at 16:15
add comment

3 Answers

up vote 3 down vote accepted

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:

  1. 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
    
  2. 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
    
share|improve this answer
    
thanks, first one worked but second one gave this error: ` Syntax error: "(" unexpected` –  TheVillageIdiot Sep 20 '11 at 14:09
    
Is this script being run by bash, or some other shell? Arrays are an extension, so more basic shells won't support them. Make sure the shebang (first line of the script) is #!/bin/bash. –  Gordon Davisson Sep 20 '11 at 17:18
add comment

I've created a similar script which does work:

FIL=~/test.txt
CMD="hostname"
touch $FIL
$CMD > $FIL

Did you try without the redirection first, to see whether the outputs get generated at all?

share|improve this answer
add comment

change:

CMD= mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'

to:

CMD="mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'"
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.