Score:0

Notifying an administrator when mail-server wasn't able to upload logs to ftp-server - if condition is failing

jo flag

I am currently working on a solution, that would notify me whenever my mail-server isn't able to transfer files to my ftp-server. (Right now my logs get rotated once per night and immediately uploaded to a separate ftp-server)

The current config is as following:


HOST="..."
USER="..."
PASS="..."
DIR="/var/log/maillogs/"
LATEST="$(ls -t $DIR | head -n 2 | tail-n 1)"
FILE=$(basename $LATEST)

error=$(ftp -n $HOST  <<EOF
quote USER $USER
quote PASS $PASS
prompt
lcd /var/log/maillogs/
cd /home/MailLog
put $FILE
quit
EOF
)
if [ $(echo $error | grep "failed")=="failed" ]
then
        *Sending Mail via sendmail*
fi

For some reason, the if condition always returns true, so I receive a mail, no matter if the files were able to be transported or not.

Does anybody know, how I would have to change the if statement to actually only get the mail, when the it's failed to transfer the log?

I also already tried the method of if [ $? -ne 0 ], but I am not too sure on how to test if it actually works. I tried giving a false IP or faulty user-logins, but by doing so, I only receive different errors.

Score:1
fr flag

[ is a built-in command and follows the same syntax rules as other commands – arguments must be quoted and space-separated.

Specifically, the operator such as == is expected to be a separate argument, so you cannot omit spaces around it. If you do, it's not interpreted as an operator – the whole thing is interpreted as [ one_arg ], the single-argument mode, in which [ returns success when the argument is non-empty.

[ $(echo $error | grep "failed") = "failed" ]
                                ^ ^

(Also, the operator is just =. While bash accepts [ x == y ], that's non-standard.)

In addition, any string expansions like $(...) need to be quoted – otherwise they'll be split up at spaces and can become multiple arguments (or worse):

[ "$(echo "$error" | grep failed)" = failed ]
  ^                              ^

All that being said, you don't actually need [ here at all – the shell's if accepts any command, so you can directly use the exit status that grep returns:

if echo "$error" | grep -qs failed; then
    echo "It failed :("
fi

Another way of doing substring checks is the case block:

case $error in
    *failed*)
        echo "Fail :("
        ;;
    *)
        echo "Success!"
        ;;
esac

If your script is using Bash specifically (i.e. if it has #!/bin/bash or such), you can simplify this using the [[ keyword, which does have some special syntax rules – the left-hand parameter doesn't actually need to be quoted, the equality operator is ==, but more usefully the right-hand value can be a wildcard comparison:

if [[ $error == *failed* ]]; then
    echo "Fail :("
fi

All that was about your shell scripting, but honestly? Throw out FTP entirely and replace it with, for example, SFTP (which runs via SSH, and you most likely already have it).

HOST="..."
USER="..."
# no PASS, it uses your id_rsa
DIR="/var/log/maillogs/"
LATEST="$(ls -t $DIR | head -n 2 | tail-n 1)"
FILE=$(basename $LATEST)

scp -p "$LATEST" "$USER@$HOST:/home/MailLog/" || {
    echo "Fail :("
}

Even better – set up remote syslog, using e.g. syslog-ng, so that messages could be streamed live to the server.

Moritz avatar
jo flag
Thank you very much for the very detailed answer. I will, for one, try out the changes that you gave me and I will look into syslog-ng. Still is there a way to test the solution you gave me?
user1686 avatar
fr flag
Change your script to upload files to the wrong path; change it to use the wrong server address; change the directory permissions to disallow uploading...
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.