LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 09-10-2006, 08:50 AM   #1
mitsos
LQ Newbie
 
Registered: Nov 2005
Location: Athens ,Greece
Distribution: slackware
Posts: 7

Rep: Reputation: 0
shell scripting


hi
i'm trying to write a shell script that reports the amount of disks space used and available.
but when i try to add them brings an error.
Code:
df -h | grep /dev/hda1 | awk '{print $3}'
14G
df -h | grep /dev/hdb1 | awk '{print $3}'
514M
i cannot add 14G and 514M
i'm looking something that would see if the last letter is G or M
and do accordingly.

if i use
Code:
df -h | grep /dev/hda1 | awk '{print $3}' | awk -F 'G| ' ' {print $1}'
removes the G and i can add them
but what about when the disk goes to M ???

any thoughts appreciated
 
Old 09-10-2006, 09:02 AM   #2
uselpa
Senior Member
 
Registered: Oct 2004
Location: Luxemburg
Distribution: Slackware, OS X
Posts: 1,507

Rep: Reputation: 46
Use df without -h, or with -k, so that the units are the same for each line.
 
Old 09-10-2006, 09:17 AM   #3
mitsos
LQ Newbie
 
Registered: Nov 2005
Location: Athens ,Greece
Distribution: slackware
Posts: 7

Original Poster
Rep: Reputation: 0
true,
but if i use it like this when i divide them i get 6,14965
how i can keep only the 6,1 or the 6,14?

thanx a lot
 
Old 09-10-2006, 11:46 AM   #4
makyo
Member
 
Registered: Aug 2006
Location: Saint Paul, MN, USA
Distribution: {Free,Open}BSD, CentOS, Debian, Fedora, Solaris, SuSE
Posts: 718

Rep: Reputation: 72
Hi, mitsos.

One way is to use a little bit of c:
Code:
#!/usr/bin/gawk -f

# @(#) a1       Demonstrate one situation of printf.

BEGIN   { n = 3.1415926 }
        { }
END     { print n
          printf("%3.2f\n",n)
        }
Running it produces:
Code:
% ./a1 /dev/null
3.14159
3.14
Change the "3.2" for width.places ... cheers, makyo
 
Old 09-10-2006, 12:28 PM   #5
makyo
Member
 
Registered: Aug 2006
Location: Saint Paul, MN, USA
Distribution: {Free,Open}BSD, CentOS, Debian, Fedora, Solaris, SuSE
Posts: 718

Rep: Reputation: 72
Hi.

There's also a stand-alone version of printf ... cheers, makyo
Code:
#!/bin/bash

# @(#) s1       Demonstrate bash builtin printf, also external on some *nix

which printf
command -V printf
pi="3.1415926"
/usr/bin/printf "%3.2f\n" $pi
command printf "%3.2f\n" $pi
Which produces:
Code:
% ./s1
/usr/bin/printf
printf is a shell builtin
3.14
3.14
 
Old 09-10-2006, 01:13 PM   #6
naflan
Member
 
Registered: May 2003
Location: NC, USA
Distribution: Slackware 13.0
Posts: 91

Rep: Reputation: 15
I don't think you can do floating point calc in bash. Try Korn shell (#!/bin/ksh)

Code:
#!/bin/ksh

hda1="`df -k | grep /dev/hda1 | awk '{print $3}'`"
hda2="`df -k | grep /dev/hda2 | awk '{print $3}'`"

ktotal=$((hda1 + $hda2))
mtotal=$((ktotal / 1024.0))
gtotal=$((mtotal / 1024.0))

printf "$ktotal k used\n"
printf "%.*f M used\n" 1 $mtotal
printf "%.*f G used\n" 1 $gtotal
which on my machine produces the following results:
Code:
1270824 k used
1241.0 M used
1.2 G used

Last edited by naflan; 09-10-2006 at 01:15 PM.
 
Old 09-10-2006, 01:42 PM   #7
mitsos
LQ Newbie
 
Registered: Nov 2005
Location: Athens ,Greece
Distribution: slackware
Posts: 7

Original Poster
Rep: Reputation: 0
thanx a lot for your replies
that helped a lot!
 
Old 09-10-2006, 01:46 PM   #8
makyo
Member
 
Registered: Aug 2006
Location: Saint Paul, MN, USA
Distribution: {Free,Open}BSD, CentOS, Debian, Fedora, Solaris, SuSE
Posts: 718

Rep: Reputation: 72
Hi, naflan.

Your ksh is better than my pdksh. I'm using "@(#)PD KSH v5.2.14 99/07/13.2" and the arithmetic didn't seem to work. I hate it when that happens. So if I'm not using awk / perl , etc., I usually end up using bc. That makes scripts more cryptic unfortunately, but the upside is that it's portable. (In the adaptation of your script, I used other disks, since I don't have an hda.) ... cheers, makyo
% cat s1
Code:
#!/bin/bash

# @(#) s1       Demonstrate calculations with bc.

disk1=hdc1
disk2=hdc3

method=ksh
method=bc

hda1="`df -k | grep /dev/$disk1 | awk '{print $3}'`"
hda2="`df -k | grep /dev/$disk2 | awk '{print $3}'`"

if [ $method = "ksh" ]
then
        echo " (Using ksh arithmetic)"
        ktotal=$(($hda1+$hda2))
        mtotal=$(($ktotal/1024.0))
        gtotal=$(($mtotal/1024.0))
else
        echo " (Using bc)"
        ktotal=$( echo "$hda1+$hda2" | bc )
        mtotal=$( echo "$ktotal/1024.0" | bc )
        gtotal=$( echo "$mtotal/1024.0" | bc )
fi

printf "$ktotal k used\n"
printf "%.*f M used\n" 1 $mtotal
printf "%.*f G used\n" 1 $gtotal
exit 0
And when run:
Code:
./s1
 (Using bc)
6320856 k used
6172.0 M used
6.0 G used
 
Old 09-10-2006, 03:14 PM   #9
makyo
Member
 
Registered: Aug 2006
Location: Saint Paul, MN, USA
Distribution: {Free,Open}BSD, CentOS, Debian, Fedora, Solaris, SuSE
Posts: 718

Rep: Reputation: 72
Hi.

I thought I had posted this, but perhaps I logged out before the final submit. My apologies if it got lost in the twisty pathways and just re-surfaced.

This uses more of the ability of awk, since that was in use earlier, and I thought it useful to show an alternative ... cheers, makyo
Code:
#!/bin/bash

# @(#) s1       Demonstrate calculations with awk.

disk1=hdc1
disk2=hdc3
disks="$disk1 $disk2"

for i in $disks
do
        df -k /dev/$i
done |
awk '
BEGIN   { sum = 0 }
/dev/   { sum += $3 }
END     { printf("%.2f k used\n", sum)
        printf("%.2f M used\n", sum / 1024)
        printf("%.2f G used\n", sum / (1024*1024))
        }'
Which then produces:
Code:
% ./s2
6320856.00 k used
6172.71 M used
6.03 G used
 
Old 09-10-2006, 07:05 PM   #10
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,695
Blog Entries: 5

Rep: Reputation: 241Reputation: 241Reputation: 241
Just an alternative, in Python

Code:
import statvfs
import os
st = os.statvfs("/boot")
print "preferred block size", "=>", st[statvfs.F_BSIZE]
print "fundamental block size", "=>", st[statvfs.F_FRSIZE]
print "total blocks", "=>", st[statvfs.F_BLOCKS]
print "total free blocks", "=>", st[statvfs.F_BFREE]
print "available blocks", "=>", st[statvfs.F_BAVAIL]
 
Old 09-11-2006, 08:53 AM   #11
makyo
Member
 
Registered: Aug 2006
Location: Saint Paul, MN, USA
Distribution: {Free,Open}BSD, CentOS, Debian, Fedora, Solaris, SuSE
Posts: 718

Rep: Reputation: 72
Hi, mitsos.

OK, with these versions, I hope you get the idea that there are lots of methods to solve a problem. Experimentation can be fun if you have the time to devote to it.

Some observations: I liked to see that ksh is still in use, even if I couldn't get pdksh to work as did naflan. You don't always need to use additional scripting methods if you are OK using utilities like bc and printf.

If you do employ other scripting languages, there are many to choose from. I often reach for perl, but the python that ghostdog74 posted was impressive in its brevity, and I liked that. I usually think of awk, perl, python, and shell as elderly, hackerly, orderly, and controllerly. No one posted a ruby script, but I suspect those will begin to show up in the future (and I'll need to think of a ly-word to describe that ).

The script below is intended to show that one can have defaults for often-used cases, but allow the flexibility of calling with different arguments. Sometimes the environment might not allow that (for example, if you need to also run code on Windows), but if it does, one can make a tool useful and general. This is clearly not the only way to do this, but it's relatively simple:
Code:
#!/bin/sh

# @(#) s4       Demonstrate calculations with awk, more general.

if [ $# -ne 0 ]
then
        partitions="$*"
else
        partitions="hdc1 hdc3"
fi

for i in $partitions
do
        echo " Looking at $i (comment out for silence)" >&2
        df -k /dev/$i
done |
awk '
BEGIN   { sum = 0 }
/dev/   { sum += $3 }
END     { printf("%.2f k used\n", sum)
        printf("%.2f M used\n", sum / 1024)
        printf("%.2f G used\n", sum / (1024*1024))
        }'
When run with no arguments:
Code:
% ./s4
 Looking at hdc1 (comment out for silence)
 Looking at hdc3 (comment out for silence)
6320856.00 k used
6172.71 M used
6.03 G used
And when run with a few SATA partitions:
Code:
% ./s4 sda6 sda7
 Looking at sda6 (comment out for silence)
 Looking at sda7 (comment out for silence)
4515732.00 k used
4409.89 M used
4.31 G used
Best wishes, and thanks to all the contributors ... cheers, makyo
 
Old 09-12-2006, 07:42 AM   #12
AnanthaP
Member
 
Registered: Jul 2004
Location: Chennai, India
Distribution: UBUNTU 5.10 since Jul-18,2006 on Intel 820 DC
Posts: 618

Rep: Reputation: 136Reputation: 136
Heres `dfspace` from a shell implemetation on Solaris. It takes the thrill out of developing but is here ASIS. Note the definition of "Blksize" and "Mbyte" as an example. Note the comment. <Quote>Filesystem may be 1K bytes/block, but, df uses 512 bytes/block.<UnQuote>

end
#!/bin/sh


#ident "@(#)adm:dfspace 1.1.2.5"

#
# dfspace - d(isk) f(ree) space
# Calculate the available disk space in all mounted filesystems
# with the exception of pseudo file systems such as /proc and /dev/df.
#
# Alternately, report on filesystems/devices specified on cmd-line.
# Filesystem may be 1K bytes/block, but, df uses 512 bytes/block.
#

/bin/df -t $* | awk '
BEGIN { FS=":"; free = -1; Blksize=512; Mbyte=1048576; CONST = Blksize / Mbyte }
{
if (free == -1) { # free is toggled every other line.
split($1,fsptr,"("); FSYS=fsptr[1]
if (NF == 3) {
split($3,freeptr," "); free=freeptr[1]+0;
} else {
split($2,freeptr," "); free=freeptr[1]+0;
}
if( free == 0 && substr(freeptr[1],1,1) != "0" ) {
free = -1; next;
}
next;
}
split($2,allocptr," "); alloc = allocptr[1]+0;
if (alloc == 0) alloc = 1; # avoid division by zero
if (free >= .005)
{
TFREE= (free * CONST) - .005; # force rounding down.
}
else
{
TFREE = (free * CONST);
}
if (alloc >= .005)
{
TALLOC= (alloc * CONST) - .005; # force rounding down.
}
else
{
TALLOC = (free * CONST);
}
PCT=free * 100 / alloc;
if (TFREE <=0) TFREE=0;
if (TALLOC <=0) TALLOC=0;

if (FSYS !~ /^\/proc/ && FSYS !~ /^\/dev\/fd/)
{
if (PCT < 25.00) { printf("%c%c%c%c",27,91,49,109) };
printf ("%s: Disk space: %#6.2f MB of %#6.2f MB available (%#5.2f%%).\n", FSYS, TFREE, TALLOC, PCT);
if (PCT < 25.00) { printf("%c%c%c%c",27,91,48,109) };
}
Cumfree += free; Cumalloc += alloc;
free = -1; # reset flag/variable for next set of two lines
}
END {
if (Cumalloc > 0) {
CumPct=Cumfree * 100 / Cumalloc;
if ((Cumfree * CONST) >=.005)
{
Cumfree= (Cumfree * CONST) - .005; # force rounding down.
}
else
{
Cumfree= (Cumfree * CONST) ;
}
if ((Cumalloc * CONST) >= .005 )
{
Cumalloc= (Cumalloc * CONST) - .005; # force rounding down.
}
else
{
Cumalloc= (Cumalloc * CONST) ;
}
printf ("\nTotal Disk Space: %#6.2f MB of %#6.2f MB available (%#5.2f%%).\n", Cumfree, Cumalloc, CumPct);
}
}'

# end of disk space calculation.
 
  


Reply

Tags
awk, shell


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 Scripting: Getting a pid and killing it via a shell script topcat Programming 15 10-28-2007 02:14 AM
shell scripting yull Linux - General 16 06-23-2006 08:05 AM
teaching shell scripting: cool scripting examples? fax8 Linux - General 1 04-20-2006 04:29 AM
shell interface vs shell scripting? I'm confused jcchenz Linux - Software 1 10-26-2005 03:32 PM
Shell Scripting, I think... AMDPwred Linux - General 1 04-06-2002 12:01 AM


All times are GMT -5. The time now is 02:35 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration