#!/bin/bash
some_array=($1)
echo "-- Setting-Up VM --"
for i in ${some_array[@]}; do
echo "VM #: $i"
case "$i" in
"1")
echo "Setting-Up VM $i"
sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@10.xx.x.xx <<EOF
pwd
nohup yes | /etc/rc.d/init.d/lifconfig
su tarts
nohup yes | vncserver
sleep 10
exit
exit
EOF
;;
"2")
echo "Setting-Up VM $i"
sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@10.xx.x.xx <<EOF
pwd
nohup yes | /etc/rc.d/init.d/lifconfig
su tarts
nohup yes | vncserver
sleep 10
exit
exit
EOF
;;
"3")
echo "Setting-Up VM $i"
sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@10.xx.x.xx <<EOF
pwd
nohup yes | /etc/rc.d/init.d/lifconfig
su tarts
nohup yes | vncserver
sleep 10
exit
exit
EOF
;;
*)
echo "unknown VM!"
;;
esac
done
Can someone please guide me I have the above script which is executed when we run the script for instance ./vmSetup.sh "1 2 3"
but this is executed sequentially. I had created this script but now I want to run the cases in the script ie 1, 2 and 3 in parallel. Can someone also tell me how to run for instance 8 cases in parallel?
Put each case... esac
statement in the background by ending it with &
. Then use wait
after the loop to wait for all the background processes to finish.
#!/bin/bash
some_array=($1)
echo "-- Setting-Up VM --"
for i in ${some_array[@]}; do
echo "VM #: $i"
case "$i" in
"1")
echo "Setting-Up VM $i"
sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@10.xx.x.xx <<EOF
pwd
nohup yes | /etc/rc.d/init.d/lifconfig
su tarts
nohup yes | vncserver
sleep 10
exit
exit
EOF
;;
"2")
echo "Setting-Up VM $i"
sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@10.xx.x.xx <<EOF
pwd
nohup yes | /etc/rc.d/init.d/lifconfig
su tarts
nohup yes | vncserver
sleep 10
exit
exit
EOF
;;
"3")
echo "Setting-Up VM $i"
sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@10.xx.x.xx <<EOF
pwd
nohup yes | /etc/rc.d/init.d/lifconfig
su tarts
nohup yes | vncserver
sleep 10
exit
exit
EOF
;;
*)
echo "unknown VM!"
;;
esac &
done
wait
Why do you have a case statement at all when all these are identical?
#!/bin/bash
echo "-- Setting-Up VM(s) --"
for i in "$@"; do
case "$i" in
1) IP=1.2.3.4;;
2) IP=2.2.3.4;;
3) IP=3.2.3.4;;
*) echo "Invalid option '$i'" >&2; exit 1;;
esac
echo "Setting-Up VM $i"
sshpass -p root12 ssh -tt -o StrictHostKeyChecking=no root@$IP <<EOF &
pwd
nohup yes | /etc/rc.d/init.d/lifconfig
su tarts
nohup yes | vncserver
sleep 10
exit
exit
EOF
done
To run a job in background, just use &
sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@$IP <<EOF &
It's just confusing because of the here-doc, but the &
metacharacter still parses correctly on my system. Try it.
Also, rather than quoting all your options in one string and then parsing them back out to an array, why not just simplify the whole thing and let them come in as separate arguments? Call it as
./vmSetup.sh 1 2 3 # NOT "1 2 3" with quotes
and the loop becomes just
for i in "$@" # properly quoted, though wouldn't matter for 1 2 3
This whole thing seems a lot simpler and easier to maintain.
Another option, which is what I would do: create a file that is a list of the DNS/IP addresses you need, then pass that file as the lone argument.
#!/bin/bash
while read -r addr || [[ -n "$addr" ]]
do echo "Setting-Up VM $addr"
sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@$addr <<EOF &
pwd
nohup yes | /etc/rc.d/init.d/lifconfig
su tarts
nohup yes | vncserver
sleep 10
exit
exit
EOF
done < "$1"
Better, add valid error checking first to make sure the file exists and is readable, etc, but as a simple case, this should work.
For even better, cleaner, safer code, read https://mywiki.wooledge.org/BashFAQ/001 and follow those suggestions. :)
If ./vmSetup.sh 1
works as expected, these should work:
parallel -j8 ./vmSetup.sh {} ::: 1 2 3 ... 100
seq 100 | parallel -j8 ./vmSetup.sh
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.