0

SSH from Host A to a few hosts (only one listed below right now) using the SSH Key I generated and then go to a specific file, grep for a specific word with a date of yesterday .. then I want to email this output to myself.

It is sending an email but it is giving me the command as opposed to the output from the command.

#!/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
3
  • Code formatting (use {} button), meaningful header (concisely reflects your problem, not emotions). Note, HOST and HOSTS are different variables. Do not use , as delimeter, just use space. Otherwise, you would have first host as XXXXXXXXXXXXXXXXXX, (with comma) Commented Feb 13, 2016 at 17:58
  • Please take a look: shellcheck.net Commented Feb 13, 2016 at 19:09
  • 1
    Code which isn't working and isn't doing anything useful is a very poor way to communicate what you want it to do. Commented Feb 15, 2016 at 19:46

2 Answers 2

1

This isn't properly an attempt to answer your question, but I think you should be aware of some fundamental problems with your code.

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

This assigns a simple string to the variable INVALID. Because of quoting issues, s/$/.\n/g is not quoted at all, and will probably be mangled by the shell. (You cannot nest single quotes -- the first single-quoted string extends from the first quote to the next one, and then WORD is outside of any quotes, followed by the next single-quoted string, etc.)

If your intent is to execute this as a command at this point, you are looking for a command substitution; with the multiple layers of uselessness peeled off, perhaps something like

INVALID=$(sed -n -e '/WORD/!d' -e "/$DATE/s/$/./p" /xxx/xxx/xxxx)

which looks for a line matching WORD and $DATE and prints the match with a dot appended at the end -- I believe that's what your code boils down to, but without further insights into what this code is supposed to do, it's impossible to tell if this is what you actually need.

COUNT=$(echo "$INVALID" | wc -c)

This assigns a number to $COUNT. With your static definition of INVALID, the number will always be 62; but I guess that's not actually what you want here.

for x in $HOSTS    
do
  ssh BLA@"$x" $COUNT

This attempts to execute that number as a command on a number of remote hosts (except the loop is over HOSTS and the variable containing the hosts is named just HOST). This cannot possibly be useful, unless you have a battery of commands named as natural numbers which do something useful on these remote hosts; but I think it's safe to assume that that is not what is supposed to be going on here (and if it was, it would absolutely be necessary to explain this in your question).

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

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

So EMAILTEXT is either an empty string or the value of INVALID. You assigned it to be a static string above, which is probably the source of your immediate question. But even if it was somehow assigned to a command on the local host, why do you need to visit remote hosts and execute something there? Or is your intent actually to execute the command on each remote host and obtain the output?

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

Piping into echo makes no sense at all, because it does not read its standard input. You should probably just have a newline after done; though a possibly more useful arrangement would be to have your loop produce output which we then pipe to mail.

Purely speculatively, perhaps something like the following is what you actually want.

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

If you want to check that there is strictly more than one line of output (which is what the -gt 1 suggests) then this may need to be a little bit more complicated.

Sign up to request clarification or add additional context in comments.

Comments

0

Your command substitution is not working. You should read up on how it works but here are the problem lines:

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

should be:

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

This inserts the value of $INVALID into the string, and puts the whole thing in single quotes. The single quotes are necessary for the ssh call so the pipes aren't evaluated in the script but on the remote host. (COUNT is changed to COUNT_CMD for readability/clarity.)

EDIT:

I misread the question and have corrected my answer.

5 Comments

I tried it that way and it executes that variable locally and not on the remote host
@Obsolete01 Wow, I misread your question, my bad. I've corrected my answer.
@Obsolete01 Can you be more specific about what happened with the above modification?
When I ran it tried to cat that file locally and then SSH'd on to the first host and done nothing
@Obsolete01 Are you using backticks in the definition of INVALID? Because single quotes won't work with that string as it contains single quotes. If you can't figure out the problem, please link to a gist/pastebin of your modified script.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.