2016-02-13 80 views
0

使用我生成的SSH密钥将主机A的SSH连接到少数主机(下面仅列出一个主机),然后转到特定文件,grep查找昨天日期的特定单词。那么我想通过电子邮件发送给我自己。使用Bash脚本的邮件输出

它正在发送一封电子邮件,但它给了我的命令而不是命令的输出。

#!/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 [email protected]"$x" $COUNT 

if [ "$COUNT" -gt 1 ]; 
then 

    EMAILTEXT="" 
     if [ "$COUNT" -gt 1 ]; 
     then 
       EMAILTEXT="$INVALID" 
     fi 
fi 

done | echo -e "$EMAILTEXT" | mail XXXXXXXXXXX.com 
+0

请查看[editing-help](http://stackoverflow.com/editing-help)。 – Cyrus

+0

代码格式(使用'{}'按钮),有意义的标题(简明地反映了你的问题,而不是情绪)。请注意,'HOST'和'HOSTS'是不同的变量。不要使用'''作为分隔符,只是使用空格。否则,您将首先使用'XXXXXXXXXXXXXXXXXX'(用逗号) –

+0

请看一下:http://www.shellcheck.net/ – Cyrus

回答

0

您的命令替换不起作用。你应该read up on how it works但这里有问题行:

COUNT=$(echo "$INVALID" | wc -c) 
[...] 
ssh [email protected]"$x" $COUNT 

应该是:

COUNT_CMD="'${INVALID} | wc -c'" 
[...] 
COUNT=$(ssh [email protected]"$x" $COUNT_CMD) 

这将插入的$INVALID值到字符串,并把整个事情的单引号。对于ssh调用,单引号是必需的,因此不会在脚本中对远程主机上的管道进行评估。 (COUNT改为COUNT_CMD的可读性/清晰度。)

编辑:

我误解的问题,并已纠正了我的答案。

+0

我试过这种方式,它在本地执行该变量,而不是在远程主机上执行 – Obsolete01

+0

@ Obsolete01哇,我误解了你的问题,我的错误。我纠正了我的答案。 – Skrat

+0

仍然没有快乐:( – Obsolete01

1

这不正确的尝试回答你的问题,但我认为你应该知道你的代码的一些基本问题。

INVALID=' cat /xxx/xxx/xxxxx | grep 'WORD' | sed 's/$/.\n/g' | grep "$DATE"' 

这将简单的字符串分配给变量INVALID。由于引用问题,s/$/.\n/g完全没有引用,并且可能会被shell损坏。 (您不能嵌套单引号 - 第一个单引号字符串从第一个引号延伸到下一个引号,然后WORD不在任何引号内,接着是下一个单引号字符串,等等。)

If你的意图是在这时执行这个命令,你正在寻找一个命令替换;与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 [email protected]"$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 [email protected]"$host" sed -n -e '/WORD/!d' -e "/$DATE/s/$/./p" /xxx/xxx/xxxx | 
    grep . || echo INVALID 
done | mail XXXXXXXXXXX.com 

如果你想检查是否有严格的输出的多行(这是-gt 1暗示什么),那么这可能需要更复杂一点。