从命令行执行此操作似乎很简单,但我无法在脚本中完成它。我试图将以下命令的输出放入文本文件中:
CMD= mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'
FIL=~/replication-`date +%F`.txt
MAILTEXT=~/mailtext.txt
touch $FIL
$CMD > $FIL
其中FIL
是包含要输出命令的文件路径的变量。我在 shell 脚本中运行此命令,我想从该脚本$FIL
使用 以附件形式通过电子邮件发送内容mutt
。但我总是得到 0 字节文件。此外,如果我在目录中检查,文件长度为 0 字节。
答案1
问题不在于重定向,而在于您如何将命令存储在变量中。首先,您不能在赋值后放置空格=
;如果那里有空格,它会将 CMD 设置为空白并运行命令mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'
。如果您只是删除空格,它会将 CMD 设置为“mysql”并尝试运行命令-uroot -psecret -e 'SHOW SLAVE STATUS \G;'
。因此,正如@Michał Šrajer 所建议的那样,您可以将其括在双引号中,以便将整个内容分配给 CMD。但它仍然不起作用,因为在$CMD
扩展时,它不会注意其中的引号。当 bash 解析命令行时,它会在扩展变量之前解析引号,因此将引号放在变量内不会产生任何有用的作用。
将命令存储在变量中比较棘手。 Bash常见问题解答#50有一些很好的讨论和选择。在这种情况下,我认为相关的选项是:
首先不要将命令放在变量中。如果没有充分的理由,请不要这样做:
FIL=~/replication-`date +%F`.txt MAILTEXT=~/mailtext.txt touch $FIL mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;' > $FIL
如果必须将命令放入变量中,请使用数组而不是简单的文本变量。在这种情况下,在创建变量时将解析引号,如果您使用它作为
"${varname[@]}"
“单词”之间的分隔符,则将保留引号:CMD=(mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;') FIL=~/replication-`date +%F`.txt MAILTEXT=~/mailtext.txt touch $FIL "${CMD[@]}" > $FIL
答案2
改变:
CMD= mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'
到:
CMD="mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;'"
答案3
我已经创建了一个类似的脚本,它可以工作:
FIL=~/test.txt
CMD="hostname"
touch $FIL
$CMD > $FIL
您是否先尝试不使用重定向,看看是否生成了输出?