2

I want a script which will restart the defined services on their respective servers. I want to pass parameter as below to the script: eg:

sh execute.sh 
Enter your server and service list: [server1:nginx,mysql],[server2:mysql,apache],[server3:mongodb,apache]

By this input the script should verify and start the services on the respective servers. I am able to do this on a single server by declaring variables.

#!/bin/bash

Instance_Name=server1
Service_Name=(nginx php-fpm mysql)
SSH_USER=admin
SSH_IDENT_FILE=~/credentials/user.pem

len=${#Service_Name[*]} 
i=0
while [ $i -lt $len ]; do 
service=${Service_Name[$i]}
ssh -i $SSH_IDENT_FILE -o StrictHostKeyChecking=no $SSH_USER@$Instance_Name 'service $service restart'
done

Now I don't have an idea to move forward. Please let me know if my question is unclear. Thanks in advance.

11
  • What about wrapping it in a big for looping through the name of servers? Commented Oct 15, 2013 at 9:01
  • @fedorqui can you give an example? Commented Oct 15, 2013 at 9:03
  • For example: while read $server; do ... (execute your script with $server parameter) .... done < list_of_servers Commented Oct 15, 2013 at 9:05
  • The array declaration is wrong. You don't have to put comma unless you want those to be part of the elements in the array. Say Service_Name=(nginx php-fpm mysql) instead. Commented Oct 15, 2013 at 9:07
  • But as I told you before I want user input like this format: [server1:nginx,mysql],[server2:mysql,apache],[server3:mongodb,apache] Commented Oct 15, 2013 at 9:08

2 Answers 2

1

Parse your input parameters

# create an array of server:services
a=($(echo "$1" | gawk 'BEGIN { FS="[]],[[]" } ; { print $1, $2, $3 }' | tr -d '[]'))
# add a for loop here to iterate values in array with code below
for var in "${a[@]}" ; do
  # get server name
  server1=$(echo $var | cut -d ':' -f1)
  # get your services as space separated
  servs1="$(echo $var | cut -d ':' -f2 | tr ',' ' ')"
  # loop your services
  for s in $servs1; do
    ssh $server1 "service $s restart"
  done
done

If you like bash programming or have to learn it this is the 'bible' to me Advanced Bash-Scripting Guide An in-depth exploration of the art of shell scripting Mendel Cooper http://www.tldp.org/LDP/abs/html/

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

4 Comments

thanks for the great help but still I am confuse how to add a loop for the first array. I am not a program though. Can you please help me by solving the puzzle.
Hi Luis, thanks for the quick response. Sure I will continue my reading on bash programming. But the above script you wrote is working for only first section of the user input [server1:nginx,mysql],[server2:mysql,apache],[server3:mongodb,apache] i.e. for server1 how to do with others? means server2 and 3
Fixed. Sorry :p forgot to other changes after adding the for loop.
Thanks Luis for your help my problem got solved. I have edited your script and now it's working fine for me.
0

Try this?

#!/bin/bash
SSH_IDENT_FILE=~/credentials/user.pem
SSH_USER=admin

# tells 'for' to read "per line"
IFS='
'

for line in $(
# read input from 1st command-line arg (not stdin)
echo "$1"|\
# remove all services except (nginx php-fpm mysql)
sed 's/\([:,]\)\(\(nginx\|php-fpm\|mysql\)\|[^]:,[]\+\)/\1\3/g'|\
# make it multi-line:
#    server1 svc1 svc2
#    server2 svc1
sed 's/\[[^]:]*:,*\]//g;s/\],*$//;s/\],*/\n/g;s/[:,]\+/ /g;s/\[//g'|\
# make it single-param:
#    server1 svc1
#    server1 svc2
#    server2 svc1
awk '{for(i=2;i<=NF;i++)print $1" "$i}'
);do
        IFS=' ' read Instance_Name service <<< $line
        echo ssh -i $SSH_IDENT_FILE -o StrictHostKeyChecking=no $SSH_USER@$Instance_Name "service $service restart"
done

Comments

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.