Let’s build a one-liner

Published on June 29, 2012 by in UNIX/Linux

0

Scenario:

It was a late, late night for you last night. You were out with you’re friends helping plan your upcoming and always fun annual houseboat vacation to Dale Hollow lake in Tennessee. (The same lake that, on one hand has a habit of eating your expensive sunglasses, but on the other hand, has provided you with many beautiful views of nature, especially the area known as “Valley of the Mist”.

Your trip is only a few weeks away and some in your group feel the need to plan – ugh, so you stay up with them until the wee hours of the morning to help get things organized and decide what and how much to bring.
(Note: For vacations to a lake, a semi-wise man once said “you only need 2 things on vacation and one of those is
optional”.)   :)

And now, it’s early, very early, Sunday morning and you’ve been awakened by your Dan Folgelberg ringtone – it’s Nagios calling.  Nagios, the eyes of your network; always watching and when needed, reporting.

After first making a mental bookmark of the dream you were enjoying, you rub your eyes and put on your bifocals to see what Nagios is needing your attention for and it seems a filesystem on the production server has filled up.

What’s a sleepy admin to do?

Of course, your first option normally would be to let the junior admin handle this late night (early morning) call but you remember last week you approved the vacation time which was requested.  Tag, you’re it.

Goal:

Display the total size of subdirectories in the filesystem using a one-line command.

Yes, we could use the find command to descend down through the filesystem to look for files in a number of ways: by size, by date, by time, etc… but our exercise today is to build a one-liner to return the size of the subdirectories under  /var.

Our first command, (du), let’s us know the total size being used in the /var filesystem. It’s using 1.5GB and we’ll pretend there has been only 1.6GB of total space allocated. (Thanks for playing along.)

[kmkaiser@classroom ~]$ sudo  /usr/bin/du -shxP  /var
1.5G    /var

Using the “ls” command, we get a full listing of the /var directory and notice there is one entry that sticks out as it is not a directory.   mail is a link to spool/mail.

[kmkaiser@classroom ~]$  ls -al  /var/
total 244
drwxr-xr-x 31 root   root    4096 May 17 10:58 .
drwxr-xr-x 28 root   root    4096 May 14 22:51 ..
drwxr-xr-x  2 root   root    4096 Jun 29 04:02 account
drwxr-xr-x  2 pcap   pcap    4096 Apr 15  2008 arpwatch
drwxr-xr-x 13 root   root    4096 Apr 15  2008 cache
drwxr-xr-x  2 root   root    4096 Nov 11  2007 crash
drwxr-xr-x  2 root   root    4096 Mar 17  2007 cvs
drwxr-xr-x  3 root   root    4096 Apr 14  2008 db
drwxr-xr-x  3 root   root    4096 Apr 14  2008 empty
drwxr-xr-x  3 root   root    4096 Dec  3  2010 ftp
drwxr-xr-x  2 root   root    4096 Mar 29  2007 games
drwxrwx–T  2 root   gdm     4096 May 14 23:00 gdm
drwxr-xr-x 28 root   root    4096 May 30 09:49 lib
drwxr-xr-x  2 root   root    4096 Mar 29  2007 local
drwxrwxr-x  6 root   lock    4096 Jun 29 04:02 lock
drwxr-xr-x 19 root   root    4096 Jun 24 04:02 log
drwx——  2 root   root   16384 Apr 14  2008 lost+found
lrwxrwxrwx  1 root   root      10 Apr 14  2008 mail -> spool/mail
drwxr-xr-x  5 nagios nagios  4096 Jun 29 12:28 nagios
drwx——  2 root   root    4096 Jun  7  2010 net-snmp
drwxr-xr-x  2 root   root    4096 Mar 29  2007 nis
drwxr-xr-x  2 root   root    4096 Mar 29  2007 opt
drwxr-xr-x  2 root   root    4096 Mar 29  2007 preserve
drwxr-xr-x  2 root   root    4096 May 19  2007 racoon
drwxr-xr-x  3 root   root    4096 May 17 10:58 rrdtool
drwxr-xr-x 24 root   root    4096 Jun 29 11:52 run
drwxr-xr-x 13 root   root    4096 Apr 14  2008 spool
drwxrwxrwt  3 root   root    4096 Jun 14 15:24 tmp
drwx——  2 root   root    4096 Jan  6  2007 tux
drwx——  3 root   bin     4096 Mar 19 14:23 webmin
drwxr-xr-x 10 root   root    4096 May 30 09:49 www
drwxr-xr-x  3 root   root    4096 Nov 10  2007 yp

Let’s re-run our above “ls” command and just return the directories, leaving out any non-directory entries whether it be links, files, sockets, etc…  To do this, we take advantage of the ability in Linux to send the output of one command into the input of a different command (known as I/O redirection) using a pipe, i.e.. ” | “.   Below, we send the output of our “ls” command into the “grep” command and ask grep to just return results that begin with a “d” (directory).

[kmkaiser@classroom ~]$  ls -al  /var/  |  grep ^d

drwxr-xr-x 31 root   root    4096 May 17 10:58 .
drwxr-xr-x 28 root   root    4096 May 14 22:51 ..
drwxr-xr-x  2 root   root    4096 Jun 29 04:02 account
drwxr-xr-x  2 pcap   pcap    4096 Apr 15  2008 arpwatch
drwxr-xr-x 13 root   root    4096 Apr 15  2008 cache
drwxr-xr-x  2 root   root    4096 Nov 11  2007 crash
drwxr-xr-x  2 root   root    4096 Mar 17  2007 cvs
drwxr-xr-x  3 root   root    4096 Apr 14  2008 db
drwxr-xr-x  3 root   root    4096 Apr 14  2008 empty
drwxr-xr-x  3 root   root    4096 Dec  3  2010 ftp
drwxr-xr-x  2 root   root    4096 Mar 29  2007 games
drwxrwx–T  2 root   gdm     4096 May 14 23:00 gdm
drwxr-xr-x 28 root   root    4096 May 30 09:49 lib
drwxr-xr-x  2 root   root    4096 Mar 29  2007 local
drwxrwxr-x  6 root   lock    4096 Jun 29 04:02 lock
drwxr-xr-x 19 root   root    4096 Jun 24 04:02 log
drwx——  2 root   root   16384 Apr 14  2008 lost+found
drwxr-xr-x  5 nagios nagios  4096 Jun 29 12:28 nagios
drwx——  2 root   root    4096 Jun  7  2010 net-snmp
drwxr-xr-x  2 root   root    4096 Mar 29  2007 nis
drwxr-xr-x  2 root   root    4096 Mar 29  2007 opt
drwxr-xr-x  2 root   root    4096 Mar 29  2007 preserve
drwxr-xr-x  2 root   root    4096 May 19  2007 racoon
drwxr-xr-x  3 root   root    4096 May 17 10:58 rrdtool
drwxr-xr-x 24 root   root    4096 Jun 29 11:52 run
drwxr-xr-x 13 root   root    4096 Apr 14  2008 spool
drwxrwxrwt  3 root   root    4096 Jun 14 15:24 tmp
drwx——  2 root   root    4096 Jan  6  2007 tux
drwx——  3 root   bin     4096 Mar 19 14:23 webmin
drwxr-xr-x 10 root   root    4096 May 30 09:49 www
drwxr-xr-x  3 root   root    4096 Nov 10  2007 yp

Our above results are in the long listing format but we just need the results for the directories listed in column 9, not all the other noise in columns 1-8.  So we’ll run our command again and send the output through the “awk” command and ask awk to pull out just column 9.

[kmkaiser@classroom ~]$ ls -al  /var/  |  grep ^d  |  awk ‘{print $9}’
.
..
account
arpwatch
cache
crash
cvs
db
empty
ftp
games
gdm
lib
local
lock
log
lost+found
nagios
net-snmp
nis
opt
preserve
racoon
rrdtool
run
spool
tmp
tux
webmin
www
yp

That’s better.  We have exactly what we need – almost.
Now it’s time to wrap a for loop around the results and add the “du” command so we can return the size for each subdirectory.   Notice the sudo command was added to gain the appropriate permissions required to descend the /var filesystem.  Without it, you will receive “Permission denied” errors.

[kmkaiser@classroom ~]$ for dir in `ls -al   /var/  | grep  ^d  |  awk ‘{print $9}’`; do sudo /usr/bin/du -shxP  /var/$dir; done

1.5G    /var/.
150G    /var/..
56M    /var/account
356K    /var/arpwatch
815M    /var/cache
8.0K    /var/crash
8.0K    /var/cvs
28K    /var/db
32K    /var/empty
8.0K    /var/ftp
8.0K    /var/games
16K    /var/gdm
120M    /var/lib
8.0K    /var/local
44K    /var/lock
444M    /var/log
16K    /var/lost+found
328K    /var/nagios
12K    /var/net-snmp
8.0K    /var/nis
8.0K    /var/opt
8.0K    /var/preserve
8.0K    /var/racoon
8.0K    /var/rrdtool
332K    /var/run
1.4M    /var/spool
96K    /var/tmp
8.0K    /var/tux
68K    /var/webmin
59M    /var/www
24K    /var/yp

If you take a look at the first two entries above, you’ll notice they are for the current “.” and parent “..” directories.  Since we just want the subdirectories under /var, let’s remove them from our output by adding a parameter to our “du” command to exclude them.

[kmkaiser@classroom ~]$ for dir in `ls -al  /var/  |  grep ^d  |  awk ‘{print $9}’`; do sudo /usr/bin/du -shxP –exclude=’..’   –exclude=’.’   /var/$dir;  done

56M    /var/account
356K    /var/arpwatch
815M    /var/cache
8.0K    /var/crash
8.0K    /var/cvs
28K    /var/db
32K    /var/empty
8.0K    /var/ftp
8.0K    /var/games
16K    /var/gdm
120M    /var/lib
8.0K    /var/local
44K    /var/lock
444M    /var/log
16K    /var/lost+found
324K    /var/nagios
12K    /var/net-snmp
8.0K    /var/nis
8.0K    /var/opt
8.0K    /var/preserve
8.0K    /var/racoon
8.0K    /var/rrdtool
332K    /var/run
1.4M    /var/spool
96K    /var/tmp
8.0K    /var/tux
68K    /var/webmin
59M    /var/www
24K    /var/yp

And now, we have reached our goal of displaying the size of each subdirectory under the /var filesystem with a one-liner.

By using the “-h” parameter to the “du” command, the sizes are easy to read but if we wanted to sort the results, we could remove the “-h” and run our output through the sort command with the “-n” parameter as displayed below.

[kmkaiser@classroom ~]$ for dir in `ls -al /var/ | grep ^d  |  awk ‘{print $9}’`; do sudo /usr/bin/du -sxP –exclude=’..’ –exclude=’.’   /var/$dir; done  |  sort -n

8    /var/crash
8    /var/cvs
8    /var/ftp
8    /var/games
8    /var/local
8    /var/nis
8    /var/opt
8    /var/preserve
8    /var/racoon
8    /var/rrdtool
8    /var/tux
12    /var/net-snmp
16    /var/gdm
16    /var/lost+found
24    /var/yp
28    /var/db
32    /var/empty
44    /var/lock
68    /var/webmin
96    /var/tmp
320    /var/nagios
332    /var/run
356    /var/arpwatch
1344    /var/spool
59444    /var/account
59824    /var/www
122264    /var/lib
456444    /var/log
833988    /var/cache

 

Command Definitions and parameters:

ls:
List information about FILEs (the current directory by default).

-a, –all
do not ignore entries starting with .

-l     use a long listing format

grep:
The grep command searches the named input FILEs (or standard input if no
files are named, or the file name – is given) for lines containing a match
to the given PATTERN.  By default, grep prints the matching lines.

The caret ^ is a meta-characters that means “beginning of the line.”
“grep ^d” is matching only lines that start with “d”.

awk:
Pattern scanning and processing language.

du:
The du command summarizes disk usage of each FILE, recursively for directories.

-s, –summarize
display only a total for each argument
-h, –human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
-x, –one-file-system
skip directories on different file systems
-P, –no-dereference
don’t follow any symbolic links (this is the default)

–exclude=PATTERN
Exclude files that match PATTERN.

sort:
Sort lines of text files

-n, –numeric-sort
compare according to string numerical value

Leave a Reply

You must be logged in to post a comment.