LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Tough script (https://www.linuxquestions.org/questions/linux-newbie-8/tough-script-696085/)

mmahulo 01-09-2009 08:30 AM

Tough script
 
hi

i want to write a script in ksh that will print the comma delimited list of Host,IP,FreeMem,averageLoad.

This is what i tried and i get lost:

cd /etc
host=`cat HOSTNAME`
cd ..
I_P=`/sbin/ifconfig`
IP=${I_P#*eth0 * inet addr:} # delete everything to the left of inet addr:
IP=${IP%% *} # delete from the right till you find the last value that variable IP now holds
echo "Host, IP"
echo $host , $IP

TotMem=`free -tm`
Tot_Mem=${TotMem#*Total: }
#Tot_Mem=${$1% *}
echo $Tot_Mem


the above script acheives to get the Host and the IP address. Please help with the remaining elements as to how i can get them. your assistance is much appreciated. thanks!

Agrouf 01-09-2009 08:35 AM

What are the remaining elements you are looking for? Can you please sum it up for me?

makuyl 01-09-2009 09:01 AM

You could experiment with these:
echo `hostname`
echo `ifconfig eth0|awk 'NR==2 {print $2}'|sed 's/^.....//'`
echo `free -t|awk 'NR==5 {print $4}'`
echo `cat /proc/loadavg`

Edit, oops, for a comma delimited something like:
echo `hostname`,`ifconfig eth0|awk 'NR==2 {print $2}'|sed 's/^.....//'`,\
`free -t|awk 'NR==5 {print $4}'`,`cat /proc/loadavg`

slack12ware 01-09-2009 09:06 AM

for averageLoad: do
echo `uname -a | cut -d ' ' -fX`

run uname on your box and check the column number loadtime avarage is in and put it where "X" is in the above command.

for freememory do:
echo `cat /proc/meminfo | grep MemFree | cut -d ' ' -f2`

play around with the value for 2 above
note the (`) they are tilda not commas. Good luck

sorry cant be of too much help aint a guru, I myself experiment and mess around a little before I come up with real scripts and am not not my box right now.

mmahulo 01-12-2009 01:08 AM

Thanks everyone.

and, makuyl is it possible to use another method except using awk as in you reply post: echo `free -t|awk 'NR==5 {print $4}'`. Or could you at least explain to me in a nutshell as to what the statement actually means. I haven't got the grips of AWK as yet. Please...

chrism01 01-12-2009 01:28 AM

@slack12ware:

~ = tilde

` = backquote

colucix 01-12-2009 02:29 AM

Here is how I would do:
Code:

#!/bin/bash
host=$(hostname -s)
ip=$(/sbin/ifconfig eth0 | sed -n '/inet /{s/.*addr://;s/ .*//;p}')
mem=$(free -tm | sed -n '/Total/{s/.* //;p}')
load=$(cat /proc/loadavg)
echo $host,$ip,$mem,$load

The hostname command with the -s option prints out the short hostname, that is without the domain name. Strip out the -s option if you want the complete hostname. To extract the data (or better to remove the unwanted parts) from the ifconfig and free output I used sed in alternative to awk or parameter substitution. Note that the total free memory is comprehensive of the swap memory.

mmahulo 01-12-2009 03:44 AM

Quote:

Originally Posted by colucix (Post 3405381)
Here is how I would do:
Code:

#!/bin/bash
host=$(hostname -s)
ip=$(/sbin/ifconfig eth0 | sed -n '/inet /{s/.*addr://;s/ .*//;p}')
mem=$(free -tm | sed -n '/Total/{s/.* //;p}')
load=$(cat /proc/loadavg)
echo $host,$ip,$mem,$load

The hostname command with the -s option prints out the short hostname, that is without the domain name. Strip out the -s option if you want the complete hostname. To extract the data (or better to remove the unwanted parts) from the ifconfig and free output I used sed in alternative to awk or parameter substitution. Note that the total free memory is comprehensive of the swap memory.


thanks colucix

i really wish to understand what the following means and right now i don't. can you please break it down for me: '/Total/{s/.* //;p}'.
Another thing is that I want total memory and not only free memory. thanks

colucix 01-12-2009 04:41 AM

To understand the sed command consider the following:
Code:

$ free -tm
            total      used      free    shared    buffers    cached
Mem:          1011        653        357          0        55        342
-/+ buffers/cache:        255        755
Swap:        2047        36      2010
Total:        3058        689      2368

from this output you want to extract the total memory from the last line. In my example I extracted just the last field "2368". So I tell to sed: for each line containing "Total" remove anything till the last blank space and print out the rest:
Code:

sed -n '/Total/{s/.* //;p}'
where /Total/ is the sed address (the commands inside brackets are executed only for those lines that match the regular expression). The command is the substitution of any number of characters .* followed by a space with nothing (that is remove this part of the line). Take in mind that a dot matches any single character and the asterisk means any number (zero included) of the preceding expression. The p command (separated by semi-colon) is to print what remains of the line after the substitution.

If you want the total memory, swap included you can do something like
Code:

free -tm | sed -n '/Total/{s/Total: *//;s/ .*//;p}'
that is first remove the first part containing Total and the following blank spaces, then remove the last part from the first blank space to the end. Or just simply use awk
Code:

free -tm | awk '/Total/{print $2}'
if you're interested in the physical memory only, just change Total with Mem in the commands above. Or just parse the content of /proc/meminfo (dividing by 1000 if you want the output in Mb)
Code:

awk '/MemTotal/{printf "%d\n",$2/1000}' /proc/meminfo

mmahulo 01-12-2009 05:30 AM

Quote:

Originally Posted by colucix (Post 3405470)
To understand the sed command consider the following:
Code:

$ free -tm
            total      used      free    shared    buffers    cached
Mem:          1011        653        357          0        55        342
-/+ buffers/cache:        255        755
Swap:        2047        36      2010
Total:        3058        689      2368

from this output you want to extract the total memory from the last line. In my example I extracted just the last field "2368". So I tell to sed: for each line containing "Total" remove anything till the last blank space and print out the rest:
Code:

sed -n '/Total/{s/.* //;p}'
where /Total/ is the sed address (the commands inside brackets are executed only for those lines that match the regular expression). The command is the substitution of any number of characters .* followed by a space with nothing (that is remove this part of the line). Take in mind that a dot matches any single character and the asterisk means any number (zero included) of the preceding expression. The p command (separated by semi-colon) is to print what remains of the line after the substitution.

If you want the total memory, swap included you can do something like
Code:

free -tm | sed -n '/Total/{s/Total: *//;s/ .*//;p}'
that is first remove the first part containing Total and the following blank spaces, then remove the last part from the first blank space to the end. Or just simply use awk
Code:

free -tm | awk '/Total/{print $2}'
if you're interested in the physical memory only, just change Total with Mem in the commands above. Or just parse the content of /proc/meminfo (dividing by 1000 if you want the output in Mb)
Code:

awk '/MemTotal/{printf "%d\n",$2/1000}' /proc/meminfo


thank you very much sir. now i get the picture. thanks again

makuyl 01-12-2009 12:09 PM

Quote:

Originally Posted by mmahulo (Post 3405313)
Thanks everyone.

and, makuyl is it possible to use another method except using awk as in you reply post: echo `free -t|awk 'NR==5 {print $4}'`. Or could you at least explain to me in a nutshell as to what the statement actually means. I haven't got the grips of AWK as yet. Please...

That one's easy to explain. I told awk to print the fourth column of the fifth line.
I didn't mean you should use those echo lines as I wrote them, just wanted to give you some ideas for a possible solution. Much cleaner to use variables like you and colucix already did.

GazL 01-12-2009 12:35 PM

IP=$(hostname -i)

may save you all that messing with ifconfig and sed to pull the ip address out.

colucix 01-12-2009 03:40 PM

Quote:

Originally Posted by GazL (Post 3405989)
IP=$(hostname -i)

may save you all that messing with ifconfig and sed to pull the ip address out.

On my system it does not display the IP of the eth0 interface, but that one of the localhost, e.g. 127.0.0.1

GazL 01-12-2009 04:14 PM

Quote:

Originally Posted by colucix (Post 3406205)
On my system it does not display the IP of the eth0 interface, but that one of the localhost, e.g. 127.0.0.1

It should return whatever the hostname resolves to. It works correctly on my system. I think some distros put the hostname on the loopback entry in /etc/hosts in order to ensure that it can always be resolved, especially if they're using a dhcp setup to get an address, so yes, on reflection, that's something to watch out for. Good spot Colucix.

It's an interesting problem. If you can't rely on 'hostname -i', then you have to parse the output of ifconfig, but then how do you decide which interface to report should you encounter a system with multiple interfaces.

colucix 01-12-2009 04:42 PM

Quote:

Originally Posted by GazL (Post 3406251)
It's an interesting problem. If you can't rely on 'hostname -i', then you have to parse the output of ifconfig, but then how do you decide which interface to report should you encounter a system with multiple interfaces.

Good point. Apparently you have to know a priori which interface to rely on. Unless there is a way to know which is the external interface and which is (are) the internal one(s), other than check the address itself after its extraction, of course. Moreover, there are a lot of different types of network interface. For example having my system at home connected via DSL modem and running OpenSuse I have
Code:

dsl0      Link encap:Point-to-Point Protocol
eth0      Link encap:Ethernet
lo        Link encap:Local Loopback
wlan0    Link encap:Ethernet
wmaster0  Link encap:UNSPEC



All times are GMT -5. The time now is 12:20 AM.