2016-02-13 115 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暗示什麼),那麼這可能需要更復雜一點。