0

I am working on a script.

  • The script runs on multiple servers.
  • It sends an email to the address mentioned in the TO field.
  • There can be one of the 2 recipients of the mail ([email protected] or [email protected]), depending on the server on which the script is executing.
  • There's a list of 4 pre-defined servers. If the script is executing on one of these servers, it sends the email to [email protected]. Else, it sends the email to [email protected].

I thought this is correct, but I missed a logic that on every server both if and else condition will be checked.

#!/bin/bash
set -x
SERVER_NAME=$(hostname -s)
FILE_TEMP=/tmp/new.log
echo -e "This is a test from SERVER_NAME" >> $FILE_TEMP
subject="sending file from $SERVER_NAME"

Servers=(flipunix1 flipunix2 flipunix3 flipunix7)
for i in ${Servers[*]}
do
    if [ "$SERVER_NAME" == "$i" ];
    then
        to="[email protected]"
        echo -e "server name picked is $SERVER_NAME and i value is $i "
        break
    else
        to="[email protected]"
        echo -e "server name picked is $SERVER_NAME and i value is $i "
        break
    fi
done

also_to="[email protected]"
mail -s "$subject" "$to" "$also_to" < $FILE_TEMP

2 Answers 2

1

It looks like you want to send to="[email protected]" if the SERVER_NAME is one within the Servers array, and if it isn't, you want to send to="[email protected]". If so, your loop logic sets to="[email protected]" and breaks the loop every time SERVER_NAME does not match -- even if SERVER_NAME may match on the next iteration. You can remedy that by removing the break, e.g.

for i in ${Servers[*]}
do
    if [ "$SERVER_NAME" = "$i" ];
    then
        to="[email protected]"
        echo -e "server name picked is $SERVER_NAME and i value is $i "
        break
    else
        to="[email protected]"
    fi
done

Now to="[email protected]" is set each time, but if the name is found in SERVER_NAME the loop exits with to="[email protected]". Only if there is no match doe the send remain to="[email protected]".

You can simply set to="[email protected]" before the loop and do:

#!/bin/bash
set -x
SERVER_NAME=$(hostname -s)
FILE_TEMP=/tmp/new.log
echo -e "This is a test from SERVER_NAME" >> $FILE_TEMP
subject="sending file from $SERVER_NAME"
to="[email protected]"

Servers=(flipunix1 flipunix2 flipunix3 flipunix7)
for i in ${Servers[*]}
do
    if [ "$SERVER_NAME" = "$i" ];
    then
        to="[email protected]"
        echo -e "server name picked is $SERVER_NAME and i value is $i "
        break
    fi
done

also_to="[email protected]"
mail -s "$subject" "$to" "$also_to" < $FILE_TEMP

That will accomplish the same thing. (you can add an if ... fi and check if [ "$to" = "[email protected]" ] if you want to output a message that that was used.)

You can also eliminate the loop entirely and simply use [[ ... ]] with the array contents and SERVER_NAME, e.g.

#!/bin/bash
set -x
SERVER_NAME=$(hostname -s)
FILE_TEMP=/tmp/new.log
echo -e "This is a test from SERVER_NAME" >> $FILE_TEMP
subject="sending file from $SERVER_NAME"
to="[email protected]"

Servers=(flipunix1 flipunix2 flipunix3 flipunix7)

[[ ${Servers[@]} =~ $SERVER_NAME ]] && {
    to="[email protected]"
    echo -e "server name picked is $SERVER_NAME "
}

also_to="[email protected]"
mail -s "$subject" "$to" "$also_to" < $FILE_TEMP

(same note on checking if [ "$to" = "[email protected]" ] if you want to output something based on that being chosen)

Let me know if I didn't understand correctly.

(note: there is only one = to check string equality in [...])

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

3 Comments

This is such a nice logic i missed it , surprisingly i used almost same logic few months ago on a script. But thank you, you showed the simplicity.
Sure, I gonna do that. I have still some doubts on the answers, once I have them,I will make sure to mark as answered.
Okay, that is fine. Generally a day or so is the normal active lifetime for a question. If you edit it will move it back active. Take as long as you like.
0

You could try this:

#!/bin/bash
set -x
SERVER_NAME=$(hostname -s)
FILE_TEMP=/tmp/new.log
echo -e "This is a test from SERVER_NAME" >> $FILE_TEMP
subject="sending file from $SERVER_NAME"

Servers=(flipunix1 flipunix2 flipunix3 flipunix7)
for i in ${Servers[*]}
do
if [ "$SERVER_NAME" == "$i" ];
then
to="[email protected]"
echo -e "server name picked is $SERVER_NAME and i value is $i "
break
fi
done

if [ -z "$to" ];
then
to="[email protected]"
echo -e "server name picked is $SERVER_NAME "
fi

also_to="[email protected]"
mail -s "$subject" "$to" "$also_to" < $FILE_TEMP

or (a shorter version)

#!/bin/bash
set -x
SERVER_NAME=$(hostname -s)
FILE_TEMP=/tmp/new.log
echo -e "This is a test from SERVER_NAME" >> $FILE_TEMP
subject="sending file from $SERVER_NAME"

Servers=(flipunix1 flipunix2 flipunix3 flipunix7)

if ! printf "%s\n" "${Servers[@]}" | grep -qw -m 1 "$SERVER_NAME";
then
to="[email protected]"
else
to="[email protected]"
fi

also_to="[email protected]"
mail -s "$subject" "$to" "$also_to" < $FILE_TEMP

6 Comments

if ! printf "%s\n" "${Servers[@]}" | grep -qw -m 1 "$SERVER_NAME"; thank you for the response. Could you help me understand the logic here? Would really help me in understand better.
Of course! First, I'm printing all the elements in the Servers array, putting them into separate lines (printf "%s\n" "${Servers[@]}"); with the grep command, we filter by the exact (-w option) first match (-m 1) and suppress the output to stdout (-q). The if statement is a stylized approach to running the command described above in a previous line and constructing the condition as if [ $? != 0 ]; then; it's just the syntax shellcheck recommended by the SC2181 standard. If you have any more questions, let me know!
The -m 1 option isn't necessary since the -q causes the grep to exit immediately when a match is found.
@Rfroes87 thanks for the explanation, the latter one is beneficial to me. And as @M. Nejat Aydin suggested, I have removed -m 1 and see no difference. Any recommendations on it?
@Rfroes87 I am also thinking, if I want to keep all the servers names in a file on same directory ( say servers_info.txt) , can i read them like below and same works? I am getting error currently . if ! echo -e servers_info.txt | grep -qw -m 1 "$SERVER_NAME"; then to="[email protected]" else to="[email protected]" fi
|

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.