LinuxQuestions.org
Latest LQ Deal: Linux Power User Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-01-2014, 06:48 PM   #1
zamykiller
LQ Newbie
 
Registered: Mar 2014
Posts: 9

Rep: Reputation: Disabled
script help


Hello everybody,

I want to make a check in nagios with a script. To check or a port is in use of a remote host.

The script makes a test connection with a host at a port (that you choose)

The problem is, it's returns a CRITICAL when it can't make a connection, this needs to be an OK, so I can know that the port is busy, already a connection.

And if it can make a connection, it need to return critical.

But i know really nothing of bash code, scrips in Linux. It's the first time i work woth Linux.
Can anybody help me to change this?

Thanks!

The script:

Code:
#!/usr/bin/perl  -w
#===============================================================================
#
#         FILE:  check_port.pl
#
#        USAGE:  check_port.pl -p <port> -h <host> (-c <critical> -w <warning> -v)
#
#  DESCRIPTION:  tests to see if the port is responding and can display timing
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Tim Pretlove
#      VERSION:  1.1
#      CREATED:  04/12/09 13:57:23
#     REVISION:  ---
#      LICENCE:  GNU
#
#       AUTHOR:  Jim Sander jim.sander@jdsmedia.net
#      VERSION:  1.2
#     MODIFIED:  03/26/14 17:34:01
#         BUGS:  Socket::pack_sockaddr_in, length is 0 error for unresolvable hostnames
#        NOTES:  Fixed; now exits with '3', status UNKNOWN, and 'host lookup failed'
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#===============================================================================

use strict;
use warnings;
use Socket;
use Getopt::Long;
use Time::HiRes qw(gettimeofday tv_interval);

my ($crit, $warn, $timeout, $host, $portnum, $verbose);
GetOptions(
    'crtitical=s'   => \$crit,
    'warning=s'     => \$warn,
    'timeout=s'     => \$timeout,
    'host=s'        => \$host,
    'port=s'        => \$portnum,
    'verbose'       => \$verbose) or HELP_MESSAGE();

sub testport {
	my ($host,$port,$protocol,$timeout) = @_;
    my $startsec;
    my $elapsed = 0;
	if (!defined $timeout) { $timeout = 10 }
	if (!defined $protocol) { $protocol = "tcp" }
	my $proto = getprotobyname($protocol);
	my $iaddr = inet_aton($host);
	if ( !defined $iaddr ){ return 3,$elapsed; }
	my $paddr = sockaddr_in($port, $iaddr);
	$startsec = [gettimeofday()];
	socket(SOCKET, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
	eval {
		local $SIG{ALRM} = sub { die "timeout" };
		alarm($timeout);
		connect(SOCKET, $paddr) or error();
		alarm(0);
	};
	if ($@) {
		close SOCKET || die "close: $!";
		$elapsed = tv_interval ($startsec, [gettimeofday]);
		return 0,$elapsed;
	} else {
		close SOCKET || die "close: $!";
		$elapsed = tv_interval ($startsec, [gettimeofday]);
		return 1,$elapsed;
	}
}
sub HELP_MESSAGE {
	print "$0 -p <port> -h <host> (-c <critical> -w <warning> -v)\n"; 
	print "\t -p <port> # port number to examine\n";
	print "\t -h <hostname> # hostname or ip address to contact\n";
	print "\t -c <seconds> # the number of seconds to wait before a going critical\n";
	print "\t -w <seconds> # the number of seconds to wait before a flagging a warning\n";
	print "\t -v # displays nagios performance information\n";
	print "\te.g $0 -p 80 -h www.google.com -c 1.5 -w 1.0 -v\n";
    exit(4);
}

sub printperf {
    my ($warning,$critical,$elapsed) = @_;
	if ((defined $warning) && (defined $critical)) {
		print "|rta=$elapsed" . "s;$warning;$critical;0;$critical";
	} else {
		print "|rta=$elapsed" 
	}
}

sub test {
    my ($critical,$warning,$host,$portnum,$timeout) = @_;
    my $proto = "tcp";
	my ($rc,$elapsed) = testport($host,$portnum,$proto,$timeout); 
	if ($rc) {
		if (defined $critical) {
			if ($critical le $elapsed) {
				return 2,$elapsed;
			}
		}
		if (defined $warning) {
			if ($warning le $elapsed) {
				return 1,$elapsed;
			}
		}
		return $rc,$elapsed;
	} else {
		return 2,$elapsed;
	}
}

unless ((defined $portnum) && (defined $host)) { 
	HELP_MESSAGE();
	exit 1;
}
if ((defined $crit) && (defined $warn)) {
	if ($crit <= $warn) {
		print "Error: warning is greater than critical will never reach warning\n";
		exit 4;
	}
}

my @mess = qw(OK WARNING CRITICAL UNKNOWN);
my @mess2 = ("is responding","is slow responding","is not responding","host lookup failed");
my ($rc,$elapsed) = test($crit,$warn,$host,$portnum,$timeout);
print "PORT $portnum $mess[$rc]: $host/$portnum $mess2[$rc]";
if (defined $verbose) {
	printperf($warn,$crit,$elapsed);
}
exit($rc);
 
Old 04-02-2014, 02:38 AM   #2
m3t3or
LQ Newbie
 
Registered: Jun 2013
Posts: 9

Rep: Reputation: Disabled
I did not read your code .. however here what I do to test if a port on a given machine is available. Maybe it can solve your problem in an easy way:
Code:
#!/bin/sh
set -e
set -u

host=192.168.0.33
echo "waiting till $host is up"
until nc -vzw 2 $host 22; do sleep 2; done
echo "$host is up now"
I am using netcat (nc) to check every 2 sec if port 22 is available at $host. ( In order to wait until the pc woke up from hybernate, so that I can connect to it )

As you can see, on the first line, this is a shell script, not a pearl script like yours.
"set -e" and "set -u" forces the script to immediately exit on error and to treat unset variables as an error .. thats makes it easy to find errors .. I always set these 2 options on each of my shell scripts.

Last edited by m3t3or; 04-02-2014 at 07:33 AM.
 
Old 04-02-2014, 03:28 AM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,246

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
So it would seem we all need to learn a little terminology:
Code:
#!/usr/bin/perl
This would indicate a Perl script (as pointed out above)
Code:
#!/bin/sh
This however is a shell script and not a bash script. It may be linked to bash but it will still not behave like a true bash script.
Here is example information:
Code:
sh
A symlink to the bash program; when invoked as sh, bash tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well
As for your problem, you have taken someone else script and found it does not work the way you have anticipated / wanted and then have asked here for others to change it for you.

You will not learn this way. At least try and work out which lines are delivering the output you are getting and do some searching on what the lines are doing so you can try to work out how to
change the output.
If you are not sure where to look, as being new to Perl and scripting in general, try searching google for Perl tutorials (there are literally 1000s).
 
Old 04-02-2014, 07:30 AM   #4
m3t3or
LQ Newbie
 
Registered: Jun 2013
Posts: 9

Rep: Reputation: Disabled
Ups ... ofc, I posted a shell script, not a bash script .. thanks for pointing out grail (fixed)
 
Old 04-02-2014, 09:23 AM   #5
zamykiller
LQ Newbie
 
Registered: Mar 2014
Posts: 9

Original Poster
Rep: Reputation: Disabled
Thanks guys, i think i did it and changed it.

For training my skills in bash, I am making a script that calculate the Humandity, Tempature and sound level form a PCB that i made.
The controller returns the value back in devisions.
So i first need to recalculate the devisions to Volt, and than I need to calculate form the volt, the tempature (component, tempaturesensor,...)

The problem now is that i need to work with float variables. After some shearching on the internet i thought i found the solution. But i get an error. This is the code.

Code:
declare -i devTemp
declare -i devHum
declare -i devSound
declare -i Hum
devTemp=$( snmpget -v 1 -c public 172.16.60.25 .1.3.6.1.4.1.19865.1.2.3.1.0 | awk '{print $4}')
devHum=$( snmpget -v 1 -c public 172.16.60.25 .1.3.6.1.4.1.19865.1.2.3.2.0 | awk '{print $4}')
devSound=$( snmpget -v 1 -c public 172.16.60.25 .1.3.6.1.4.1.19865.1.2.3.3.0 | awk '{print $4}')
echo "reading succesfull"
echo "sound = $devSound"

Hum=`echo (($devHum * 0.003225)  - 0.674)  / 0.02625 |bc`
echo "hum = $Hum"
I get this error: command substitution: line 11: syntax error near unexpected token `('

I don't know how to work with float integers and the internet doesn't help me.

Last edited by zamykiller; 04-02-2014 at 09:32 AM.
 
Old 04-02-2014, 10:15 AM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,246

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
Well the first point would be that bash does not perform anything but integer calculations ... hence the requirement for your script to call bc.

I do see several issues:

1. you declare Hum as an integer but I would almost guarantee that the calculation returned from bc will be anything but an integer

2. you report, 'reading successful', how do you know this? Do you assume that all the previous lines have worked fine and so reaching this line tells you success?? This logic is well flawed

3. why do you change from using $() to ``? It is not particularly an issue but requires the reader to be aware of both forms for no reason

4. what is the point of returning the value of devTemp when it is never used in the rest of the script?

5. your error points to the fact that none of the mathematics has been protected from the shell with quotes prior to being passed to bc


You may find it easier to have awk perform all your calculations, as it can handle floating point numbers, by having it read all values from snmpget and giving you the output required
 
Old 04-03-2014, 03:48 AM   #7
zamykiller
LQ Newbie
 
Registered: Mar 2014
Posts: 9

Original Poster
Rep: Reputation: Disabled
I used your advice, there is a little bit progress now.
I did it to do the calculation.
But when i want to do a compersion (if), the script always go into the if, and never in the else.
Even when the value is lower than 30.

Code:
declare -i devTemp
declare -i devHum
declare -i devSound

num1=30
devTemp=$( snmpget -v 1 -c public 172.16.60.25 .1.3.6.1.4.1.19865.1.2.3.1.0 | awk '{print $4}')
devHum=$( snmpget -v 1 -c public 172.16.60.25 .1.3.6.1.4.1.19865.1.2.3.2.0 | awk '{print $4}')
devSound=$( snmpget -v 1 -c public 172.16.60.25 .1.3.6.1.4.1.19865.1.2.3.3.0 | awk '{print $4}')

Hum=$(echo "scale=8; ( ( $devSound * 0.003225 )  - 0.674 ) / 0.02625" |bc)
echo "hum = $Hum"

Temp=$(echo "scale=8; ( ( $devSound * 0.003225 ) - 0.5 ) / 0.01" |bc)
echo "temp =$Temp"

compare_result_temp=$( echo "$Temp > $num1" |bc)
if [ $compare_result_temp ]; then
echo "Temperatuur to big"
else
echo "Temperatuur ok"
fi
 
Old 04-03-2014, 04:08 AM   #8
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,246

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
Your if simply tests if the variable has a value not zero stored in it ... btw using single brackets [] will get an error should the variable not be set at all.

Also, assuming you are getting a return value from the bc to compare_result_temp, what would you expect to be stored in the variable???

Try placing the following under the interpreter in your script:
Code:
set -xv
This will give you put to show you what is happening at each line
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Shell script/Perl Script to remove the string until it finds special character '_' pooppp Programming 10 07-17-2012 10:36 AM
Shell script, Perl script, command or utility to convert Binary to text Perseus Programming 26 07-12-2012 07:00 AM
[SOLVED] bash and xterm: how make apps started by and for a script persist when script terminates porphyry5 Linux - General 4 06-15-2011 02:27 PM
[SOLVED] Script question: create a shell script in kde to log in on a server with ssh c4719929 Linux - Newbie 1 01-31-2011 04:05 AM
How to get full path to script file inside script itself? And in case of sym links? maggus Linux - Newbie 3 05-28-2009 09:40 AM


All times are GMT -5. The time now is 10:36 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration