使用我生成的 SSH key 从主机 A 到几台主机(现在只有下面列出的一台)SSH,然后转到特定文件,用 grep 查找日期为昨天的特定单词..然后我想发送电子邮件这个输出给我自己。
它正在发送一封电子邮件,但它给我的是命令而不是命令的输出。
#!/bin/bash
HOST="XXXXXXXXXXXXXXXXXX, XXXXXXXXXXXXX"
DATE=$(date -d "yesterday")
INVALID=' cat /xxx/xxx/xxxxx | grep 'WORD' | sed 's/$/.\n/g' | grep "$DATE"'
COUNT=$(echo "$INVALID" | wc -c)
for x in $HOSTS
do
ssh BLA@"$x" $COUNT
if [ "$COUNT" -gt 1 ];
then
EMAILTEXT=""
if [ "$COUNT" -gt 1 ];
then
EMAILTEXT="$INVALID"
fi
fi
done | echo -e "$EMAILTEXT" | mail XXXXXXXXXXX.com
最佳答案
这并不是试图回答您的问题,但我认为您应该了解您的代码的一些基本问题。
INVALID=' cat /xxx/xxx/xxxxx | grep 'WORD' | sed 's/$/.\n/g' | grep "$DATE"'
这将一个简单的字符串分配给变量 INVALID
。由于引用问题,s/$/.\n/g
根本没有被引用,并且可能会被 shell 破坏。 (您不能嵌套单引号——第一个单引号字符串从第一个引号延伸到下一个引号,然后 WORD
在任何引号之外,然后是下一个单引号字符串,等等.)
如果此时您打算将此作为命令执行,则您正在寻找命令替换;多层 uselessness剥掉了,也许像
INVALID=$(sed -n -e '/WORD/!d' -e "/$DATE/s/$/./p" /xxx/xxx/xxxx)
查找与 WORD
和 $DATE
匹配的行,并在末尾附加一个点来打印匹配项——我相信这就是您的代码归结为的内容,但是如果不深入了解这段代码应该做什么,就不可能判断这是否是您真正需要的。
COUNT=$(echo "$INVALID" | wc -c)
这为 $COUNT
分配了一个数字。使用 INVALID
的静态定义,数字将始终为 62;但我想这实际上不是您想要的。
for x in $HOSTS
do
ssh BLA@"$x" $COUNT
这将尝试在多个远程主机上将该数字作为命令执行(除了循环结束 HOSTS
并且包含主机的变量仅命名为 HOST
) .这不可能有用,除非你有一组命名为自然数的命令,这些命令在这些远程主机上做一些有用的事情;但我认为可以安全地假设这不是这里应该发生的事情(如果是的话,绝对有必要在你的问题中解释这一点)。
if [ "$COUNT" -gt 1 ];
then
EMAILTEXT=""
if [ "$COUNT" -gt 1 ];
then
EMAILTEXT="$INVALID"
fi
fi
因此 EMAILTEXT
要么是一个空字符串,要么是 INVALID 的值。您将其指定为上面的静态字符串,这可能是您直接问题的来源。但即使它以某种方式分配给本地主机上的命令,为什么您需要访问远程主机并在那里执行某些操作?或者您的意图实际上是在每个远程主机上执行命令并获取输出?
done | echo -e "$EMAILTEXT" | mail XXXXXXXXXXX.com
通过管道输入 echo
完全没有意义,因为它不读取其标准输入。你应该在 done
之后有一个换行符;尽管一个可能更有用的安排是让您的循环产生输出,然后我们将其通过管道传输到 mail
。
纯粹是推测,也许像下面这样的东西才是您真正想要的。
for host in $HOSTS; do
ssh BLA@"$host" sed -n -e '/WORD/!d' -e "/$DATE/s/$/./p" /xxx/xxx/xxxx |
grep . || echo INVALID
done | mail XXXXXXXXXXX.com
如果你想检查输出是否严格超过一行(-gt 1
建议),那么这可能需要稍微复杂一些。
关于linux - 使用 Bash 脚本输出邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35383220/