Archive for December, 2009

Useful use of pgrep

December 26, 2009 1 comment

To list the PIDs of all running process_name, instead of

ps ax|grep process_name|grep -v grep|awk '{print $1}'


pgrep process_name

To kill all running process_name, instead of

for p in `ps ax|grep process_name|grep -v grep|awk '{print $1}'`; do kill $p; done


pkill process_name

Categories: Bash, linux, Programming

check host is alive or not with perl Net::Ping

December 26, 2009 9 comments

With Bash

chost() {
    up=`ping -c 1 -W $2 $1|grep 100%`
    return `test -z "$up"`
[ $# -lt 1 ] && "Usage is: $0 host [timeout=5]" && exit 1
[ $# -gt 1 ] && timeout=$2 || timeout=5
chost $1 $timeout && echo "$1 is alive"

Problem with this script:
If the default route is missing when running this script to test an external host, the result will show the host is alive, along with the following ping error:
connect: Network is unreachable

Hence the (improved) version of ping script with Perl:

With Perl

#!/usr/bin/perl -w
use Net::Ping;
use Switch;

if (@ARGV >1) { $host=$ARGV[0]; $timeout=$ARGV[1]; }
elsif (@ARGV>0) { $host=$ARGV[0]; $timeout=5; }
else { print "Usage is: $0 host <timeout=5>\n"; exit; }

print "$host is alive.\n" if $p->ping($host, $timeout);

Embed perl in bash

I found it quite handy to use the above perl script in some of my gateway management bash scripts.

chost() {
export host=$1
export timeout=$2
a=`perl -MNet::Ping -e '$p=Net::Ping->new('icmp'); \
   if( $p->ping($ENV{'host'},$ENV{'timeout'}) ) \
           {print "OK";} \
   else {print "BAD";} \ 
return `test $a == "OK"`
[ $# -lt 2 ] && echo "Usage is: $0 host timeout" && exit 0
chost $1 $2 && echo "good" || echo "not good"

Gnome Desktop: Where is the active wallpaper located?

December 26, 2009 1 comment

I have been a big fan of Gnome Desktop Environment due to its simplicity. But sometimes simplicity can lead to annoyance. For one, let’s look at the wallpaper dialog in GDE: suppose I spot a very interesting wallpaper on my friend’s PC and I would like to know where it’s located. I thought that’s easy: right-click on the desktop and choose Change Background, somewhere on the screen should tell you the full path of the wallpapers pool. Unfortunately it doesn’t tell you any information about all the wallpaper images, including the file paths. Interestingly enough, if want to add a new wallpaper to the pool, you click the Add button and browse to where the image file is located and click OK button (there exist other ways to add wall papers to the pool of course), meaning you know exactly where the wallpaper is located if you add one this way. But once you are done, unless you write down (or store it somewhere on your PC) about where the file is located, you lose track of the wallpapers completely.

Some of you might point out the locations of the wallpapers are all in the file ~/.gnome2/backgrounds.xml. True, all file locations are in there, but it won’t tell you which one is currently active. Plus, having to open that file (or something alike) in order to know the location of the wallpapers is a bit overkill for someone, say, absolute newbie. I understand that knowing exactly where the active wallpaper is located is not a common feature that everyone would ask for, but not providing a simple way to figure it out is indeed very annoying.

So far, I haven’t figure out a good solution to this problem.

Batch-processing script

December 17, 2009 Leave a comment

I have developed this batch-processing script that’ll chop down files under a directory and process each group of files. Currently this bash script has the following features:
1) preview mode (option -p) lets you preview what commands will be executed
2) group files based on either
a) fixed number of files, for example, every 20 files
b) fixed bytes of file size sum, for example, every 10 MB
3) allow file list generation (which defaults to command find) to be customized by user
4) supports environment variable $VOL when the processing program is shell script (and is able to use environment variables)

For detail usage and examples, simply run without any parameters.

View the code in (pretty) html format
View the raw codes in pure text format
[ Rename to after downloading, the same step should be done for the following example scripts. ]
Example code 1:
Example code 2:

Feedbacks or comments are welcome.

Categories: Bash, Programming

Watch out these bash wildcards

December 15, 2009 Leave a comment

I would like to list a couple of mistakes I used to make often when using Linux commands:

1. Remove contents of a folder with rm
Let’s say I have a folder ~/data/docs and I want to empty it. There are hidden files (files that start with . ) along with files with regular names.
The wrong way:

$ rm -rf ~/data/docs/*

the above command will remove all files and directories under ~/data/docs except the hidden ones.

The right way:

$ rm -rf ~/data/docs/* ~/data/docs/.* 2>/dev/null


$ rm -rf ~/data/docs/{*,.*} 2>/dev/null

Note: the trailing 2>/dev/null suppresses the following error messages

rm: cannot remove `.' directory `/home/rico/data/docs/.'
rm: cannot remove `..' directory `/home/rico/data/docs/..'

An even better way

$ cd ~/data/docs
$ find . -delete

Note: using only the find command

find ~/data/docs -delete

will delete the folder ~/data/docs as well, hence the cd command.


2. Rsync contents of folder src with dest
The wrong way: (unless copying only non-hidden items is the goal)

$ rsync -av /path/to/src/* /path/to/dest/

Similar to the rm mistake. Using rsync this way will only copy non-hidden files and folders from src/ to dest/

The right way:

$ rsync -av /path/to/src/ /path/to/dest/

Be careful not to type this instead [ without the trailing slash after src ]:

$ rsync -av /path/to/src /path/to/dest/

as that will put folder src instead of the content of it under /path/to/dest, that is, after running the above command, the destination folder structure will have the following folder:

Categories: Bash, Tip

Extract ip address(es) from standard input using perl and regular expression

December 15, 2009 3 comments

Method 1:

$ cat file | perl -nle 'print "$1" if

Method 2:

$ cat file | perl -nle 'print $1 if /(([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+))/g && $2<256 && $3<256 && $4<256 && $5<256'

I prefer using method 2 because it’s simpler to construct and for ip addresses such as (obvious an invalid one), using method 1 results in1.2.3.123 being matched. But method 2 will not mistakingly pick up that ip address.

Reference: Mastering Regular Expressions by Jeffrey E.F. Friedl.

Categories: perl, Programming

Top reasons I don’t like Grub2

December 13, 2009 1 comment

Recently I replaced my ubuntu 9.04 with LinuxMint 8 which uses Grub2 as the boot loader and I found it quite annoying for the following reasons:

1) There is no more /boot/grub/menu.lst to edit, instead, any new boot entries should be inserted into /etc/grub.d/40_custom

2) Adding a new boot entry or modifying boot settings (such as default timeout value) requires an additional command in order for the new settings to become effective:
[ update-grub also works ]

3) Because of the above reasons, if the LinuxMint can’t boot due to some misconfiguration in the grub setting, it becomes harder to get it repaired since you run into the egg-and-chicken dilemma: you have to boot into LinuxMint in order to get grub2 repaired and updated [ which is exactly the reason I don’t like using boot loader lilo ]

4) The syntax has changed in grub2 for boot entries: among other changes, kernel is now replaced with linux, initrd is replaced with module (and module supports loading other things, this seems to be the only + point for grub 2)

All in all I was not impressed with the new “features” introduced by grub2 and as a result I downgraded it to grub using the other OS (Centos 5.4) on the same hard drive.