I have scenario where I have list of 100s of server . Want to check whether those all server can reach to specified destination server or not by telneting from all server to that destination server.
I have written a code as below,
#!/bin/bash
#bash to check telnet status.
#set -x;
#
#clear
SetParam() {
export URLFILE="Host_PortFile.txt"
export TIME=`date +%d-%m-%Y_%H.%M.%S`
export port=80
export STATUS_UP=`echo -e "\E[32m[ RUNNING ]\E[0m"`
export STATUS_DOWN=`echo -e "\E[31m[ DOWN ]\E[0m"`
export MAIL_TO="admin(at)techpaste(dot)com"
export SHELL_LOG="`basename $0`.log"
}
Telnet_Status() {
SetParam
cat $URLFILE | while read next
do
server=`echo $next | cut -d : -f1`
port=`echo $next | awk -F":" '{print $2}'`
TELNETCOUNT=`sleep 5 | telnet $server $port | grep -v "Connection refused" | grep "Connected to" | grep -v grep | wc -l`
if [ $TELNETCOUNT -eq 1 ] ; then
echo -e "$TIME : Port $port of URL http://$server:$port/ is \E[32m[ OPEN ]\E[0m";
else
echo -e "$TIME : Port $port of URL http://$server:$port/ is \E[31m[ NOT OPEN ]\E[0m";
echo -e "$TIME : Port $port of URL http://$server:$port/ is NOT OPEN" | mailx -s "Port $port of URL $server:$port/ is DOWN!!!" $MAIL_TO;
fi
done;
}
Main() {
Telnet_Status
}
SetParam
Main | tee -a $SHELL_LOG
My Host_PortFile.txt file looks like,
gmail.com:443
But here, i need to go to individual server and has to run this which consumes more time. Is there any modification I can do so that I can run the script from one machine to read all source server name from text file or any and can check that server can reach the destination server or not? Can anyone suggest on this please?
Related
I want to create a script that execute a command when wlan0 if connected to a specific ip. If connected to a different ip, launch a different command (I have a static ip)
I want to avoid launching this script in public wifi.
I hope you guys understand. English is not my main langage
Run this script in script in system startup
cal()
{
a=$(ip addr | grep "wlan0" | sed '1d' |awk '{print $2}' | sed -e 's/\(.*\)...$/\1/')
echo $a
b=10.98.35.96
if [ $b = $a ]
then
echo same
#give command
kill -9 $$
else
echo notsame
sleep 3
cal
fi
}
cal
Hey all I have the following BASH script running at startup on my WRT1900ac linksys:
USER="admin"
PASS="passhere"
PROTOCOL="http"
ROUTER_IP="192.168.1.1"
# Port to connect to which will provide the JSON data.
PORT=9898
while [ 1 ]
do
# Grab connected device MAC addresses through router status page.
MACS=$(curl -s --user $USER:$PASS $PROTOCOL://$ROUTER_IP/Status_Wireless.live.asp)
# clear temp JSON file
echo > temp.log
# Get hostname and IP (just in case there is no hostname).
for MAC in $(echo $MACS | grep -oE "wl_mac::[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}:[a-z0-9]{2}" | cut -c 9-);
do
grep 0x /proc/net/arp | awk '{print $1 " " $4}' | while IFS= read -r line
do
IP=$(echo $line | cut -d' ' -f1)
MACTEMP=$(echo $line | cut -d' ' -f2)
HOST=$(arp -a | grep $IP | cut -d' ' -f1)
# if no hostname exists, just use IP.
if [ "$HOST" == "" ]
then
HOST=$IP
fi
if [ "$MAC" == "$MACTEMP" ]
then
JSON="{'hostname' : '$HOST', 'mac_address' : '$MAC'}"
echo $JSON >> temp.log
fi
done
done
# Provide the JSON formatted output on $PORT of router.
# This allows one connection before closing the port (connect, receive data, close).
# Port will reopen every 5 minutes with new data as setup in a cron job.
echo -e "HTTP/1.1 200 OK\n\n $(cat temp.log)" | nc -l -p$PORT >/dev/null
# Wait for 10 seconds and do it all over.
sleep 10
done
And for some reason when I reboot the router and then try to visit http://192.168.1.1:9898 it just shows a blank page even though I have my android cell phone connected via wifi to the router and the router shows the MAC address on the status page.
What should be on that page is all the wireless MAC address that are currently connected to the router and displaying them out in JSON form.
Any BASH guru's here that can help spot the problem?
I think it should be
echo -e "HTTP/1.1 200 OK\n\n $(cat temp.log)" | nc -l -p$PORT 0.0.0.0 >/dev/null
I'm trying to "ping" if some applications are running in some remote machines.
To do that I have a file with the servers and applications, like:
server1:application1
server2:application1
server3:application2
Etc.
I expect to obtain the number of applications with this name that are running in the server.
To connect and to check I need a ssh connection.
My script is a bash and is like this:
Ping_Applications () {
SetParam
cat $APPFILE | while read next
do
server=`echo $next | cut -d : -f1`
app=`echo $next | awk -F":" '{print $2}'`
commando="/bin/ssh $server '/bin/ps -fea | /bin/grep $app | /bin/grep -v grep | /bin/wc -l'"
eval COMA=\$\($commando\)
echo $commando
if [ $COMA != 0 ]
then
echo -e "$TIME : Application $app of on server $server is \E[32m[ RUNNING ]\E[0m";
else
echo -e "$TIME : Application $app of on server $server is \E[31m[ NOT RUNNING ]\E[0m";
fi
done;
}
My problem is that when I send
ssh $server 'ps -fea | grep $app | grep -v grep | wc -l'
This returns the number, but when is sent by using the script, I have not answer, because (I think) the pipe open a new shell.
I don't know how to solve this.
Any idea?
Thanks
Luis
This is Bash FAQ 50
You want to put the command in an array, and not use eval to invoke it:
commando=( /bin/ssh $server '/bin/ps -fea | /bin/grep "'"$app"'" | /bin/grep -v grep | /bin/wc -l' )
COMA=$( "${commando[#]}" )
commando is an array with 3 elements, so the last element can be passed to the remote server as a single word. Note the careful quoting around $app
Also, since $COMA will be a number, use numeric comparison: if [ $COMA -ne 0 ]
You might want to separate the /bin/ssh command and its arguments. Also put the "commando" in double quotes:
Instead of:
commando="/bin/ssh $server '/bin/ps -fea | /bin/grep $app | /bin/grep -v grep | /bin/wc -l'"
eval COMA=\$\($commando\)
Try this:
commando="/bin/ps -fea | /bin/grep $app ..."
/bin/ssh $server "$commando"
Bash variables gets expanded in double quotes, but not in single quotes.
Thanks for your help
I mixed the answers from Eric Renouf and Glenn Jackman and the solution es like this:
Ping_Applications () {
SetParam
cat $APPFILE | while read next
do
server=`echo $next | cut -d : -f1`
app=`echo $next | awk -F":" '{print $2}'`
commando=( /bin/ssh $server '/bin/pgrep -f "'"$app"'" | /bin/wc -l' )
COMA=$( "${commando[#]}" )
if [ $COMA -gt 0 ]
then
echo -e "$TIME : Application $app of on server $server is \E[32m[ RUNNING ]\E[0m";
else
echo -e "$TIME : Application $app of on server $server is \E[31m[ NOT RUNNING ]\E[0m";
fi
done;
}
Now i have a different problem:
This solution works, but only for the first input, then the script stops.
I have around 10 different applications in my $APPFILE, but only the first one is executed.
Regards.
Luis
Have a slew of services that run as part of a hadoop stack; want a simple CLI script that checks the various processes and gives a simple output for end user.
There will be over 50 hosts; and around 10 services it will need to check on each host.
Currently written in bash; I like the output but the code is slllloooowww as it checks each process; 1 at a time via passwordless ssh and pgrep.
Looking for advice or hints on making this faster.
ie:
Hostname | IP | Ping | SSH | Zookeeper | Namenode | Datanode
localhost | 127.0.0.1 | online | online | _ | _ | _
node1 | 172.30.50.150 | online | online | _ | _ | _
dn1 | 10.142.0.100 | online | online | online | online | online
sample code:
fun_datanode () {
zup=`ssh $1 "ps ax | grep -v grep | grep datanode | wc -l"`
if [ $zup -gt 0 ]; then
dn=online
else
dn="_"
fi
}
#main
#main loop that reads host file
for host in `awk '/^[0-9]/ { print $1 }' /etc/hosts`
do
#ping
fping -c1 -t10 -n $host > /dev/null 2>&1
RETVAL=$?
hname=`getent hosts $host | awk '{print $2 }'`
if [ $RETVAL -eq 0 ]; then
if ssh $host 'pgrep ssh' > /dev/null 2>&1; then
ssh=online
fun_zookeeper $host
fun_namenode $host
fun_datanode $host
fi
fun_print "$hname $host "online" $ssh $zoo $nn $dn"
echo
else
fun_print $hname $host "${red}offline${norm}" "_" "_" "_" "_"
echo
fi
done
You should use Ganglia or Ambari to monitor large clusters. They are free and open source. They have monitoring as well as alerting capabilities based up on thresholds.
There are utilities like pdsh (parallel distributed shell)
https://code.google.com/p/pdsh/wiki/UsingPDSH
This can be used to run process checks in parallel on many nodes.
Parallel SSH was archived (read-only) in Google Code. For more up-to-date releases see https://github.com/pkittenis/parallel-ssh .
Another option is Fabric:
http://www.fabfile.org/
Found a working solution without scope creeping into a major project;
Instead of going to the well each time for getting process status on node via SSH; grab the ps ax once on every node then assign to local variable. Then interrogate the variable each time for current process status.
Instead of doing (amount of nodes X amount of services) = SSH connections; now it only does (amount of nodes) = SSH connections.
From there; I may background / fork each SSH...
fun_grabps () {
psout=`ssh $1 "ps ax"`
}
fun_zookeeper () {
zup=`echo $psout | grep -v grep | grep zoo | wc -l`
if [ $zup -gt 0 ]; then
zoo=online
else
zoo="_"
fi
}
I need to check if Tomcat is running in my system via a shell script. If not I need to catch the process id and kill Tomcat. How shall it be achieved?
in order to get the running process, I've used this command:
ps x | grep [full_path_to_tomcat] | grep -v grep | cut -d ' ' -f 1
You have to be careful, though. It works on my setup, but it may not run everywhere... I have two installations of tomcat, one is /usr/local/tomcat on port 8080 and /usr/local/tomcat_8081 on port 8081. I have to use '/usr/local/tomcat/' (with the final slash) as the full_path because otherwise it would return 2 different pids if tomcat_8081 is running as well.
Here's the explanation of what this command does:
1) ps x gives you a list of running processes ordered by pid, tty, stat, time running and command.
2) Applying grep [full_path_to_tomcat] to it will find the pattern [full_path_to_tomcat] within that list. For instance, running ps x | grep /usr/local/tomcat/ might get you the following:
13277 ? Sl 7:13 /usr/local/java/bin/java -Djava.util.logging.config.fil
e=/usr/local/tomcat/conf/logging.properties [...] -Dcatalina.home=/usr/local/tomca
t [...]
21149 pts/0 S+ 0:00 grep /usr/local/tomcat/
3) As we get 2 entries instead of one due to the grep /usr/local/tomcat/ matching the pattern, let's remove it. -v is the invert-match flag for grep, meaning it will select only lines that do not match the pattern. So, in the previous example, using ps -x | grep /usr/local/tomcat/ | grep -v grep will return:
13277 ? Sl 7:13 /usr/local/java/bin/java -Djava.util.logging.config.fil
e=/usr/local/tomcat/conf/logging.properties [...] -Dcatalina.home=/usr/local/tomca
t [...]
4) Cool, now we have the pid we need. Still, we need to strip all the rest. In order to do that, let's use cut. This command removes sections from a FILE or a standard output. The -d option is the delimiter and the -f is the field you need. Great. So we can use a space (' ') as a delimiter, and get the first field, which corresponds to the pid. Running ps x | grep /usr/local/tomcat/ | grep -v grep | cut -d ' ' -f 1 will return:
13277
Which is what you need. To use it in your script, it's simple:
#replace below with your tomcat path
tomcat_path=/users/tomcat/apache-tomcat-8.0.30
pid=$(ps x | grep "${tomcat_path}" | grep -v grep | cut -d ' ' -f 1)
if [ "${pid}" ]; then
eval "kill ${pid}"
fi
One way to check by using wget for your server address and checking the status.
Check this link here :
http://www.velvettools.com/2013/07/shell-script-to-check-tomcat-status-and.html#.VX_jfVz-X1E
TOMCAT_HOME=/usr/local/tomcat-folder/
is_Running ()
{
wget -O - http://yourserver.com/ >& /dev/null
if( test $? -eq 0 ) then
return 0
else
return 1
fi
}
stop_Tomcat ()
{
echo "shutting down......"
$TOMCAT_HOME/bin/shutdown.sh
}
start_Tomcat ()
{
echo "starting......"
$TOMCAT_HOME/bin/startup.sh
}
restart ()
{
stop_Tomcat
sleep 10
kill_Hanged_Processes
start_Tomcat
sleep 60
}
the easy way to do that is :
ps -ef | grep tomcat
by using this command you'll get :
user [id-to-kill] Date [tomcat-path]
last step is killing the process
sudo kill -9 [id-to-kill]
Congratulation, your process was killed lOol
Tomcat's default port is 8080. u can grep it and use port status in comparision loop.
#!/bin/bash
STAT=`netstat -na | grep 8080 | awk '{print $7}'`
if [ "$STAT" = "LISTEN" ]; then
echo "DEFAULT TOMCAT PORT IS LISTENING, SO ITS OK"
elif [ "$STAT" = "" ]; then
echo "8080 PORT IS NOT IN USE SO TOMCAT IS NOT WORKING"
## only if you defined CATALINA_HOME in JAVA ENV ##
cd $CATALINA_HOME/bin
./startup.sh
fi
RESULT=`netstat -na | grep 8080 | awk '{print $7}' | wc -l`
if [ "$RESULT" = 0 ]; then
echo "TOMCAT PORT STILL NOT LISTENING"
elif [ "$RESULT" != 0 ]; then
echo "TOMCAT PORT IS LISTENINS AND SO TOMCAT WORKING"
fi
this way you can compare the script.you grep port 8080 if you are using the default port for tomcat.this will only check whether tomcat is running.
then you can check the processes using the port
lsof -i:8080 //if using port 8080
the if you want to free the port by killing the process using it use this command
kill 75782 //if for instance 75782 is the process using the port