将命令输出重定向到文件

将命令输出重定向到文件

从命令行执行此操作似乎很简单,但我无法在脚本中完成它。我试图将以下命令的输出放入文本文件中:

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有一些很好的讨论和选择。在这种情况下,我认为相关的选项是:

  1. 首先不要将命令放在变量中。如果没有充分的理由,请不要这样做:

    FIL=~/replication-`date +%F`.txt
    MAILTEXT=~/mailtext.txt
    
    touch $FIL
    mysql -uroot -psecret -e 'SHOW SLAVE STATUS \G;' > $FIL
    
  2. 如果必须将命令放入变量中,请使用数组而不是简单的文本变量。在这种情况下,在创建变量时将解析引号,如果您使用它作为"${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

您是否先尝试不使用重定向,看看是否生成了输出?

相关内容