Mounting Debian ISO files as Offline Software Repository


If you are not connected to internet, then still you can install packages
from Debian Installer ISOs.

For example, if Debian 7.0 (Wheezy) ISOs are in directory /media/FreeAgent GoFlex Drive/Softwares/Debian_7.0_Wheezy
directory and we want to mount these iso in /mnt/Debian/ directory. The following command can be used:

$ sudo $(which mount_debian.pl) -d /mnt/Debian -g -r "/media/FreeAgent GoFlex Drive/Softwares/Debian_7.0_Wheezy"
Using iso(s) dir '/media/FreeAgent GoFlex Drive/Softwares/Debian_7.0_Wheezy'
Using mount point dir '/mnt/Debian'
...
Total 11 iso(s) mounted successfully.

Unmounting of the iso(s) can be achieved by the following command:

$ sudo $(which mount_debian.pl) -d /mnt/Debian -u -g -r
Running: umount "/mnt/Debian"/*.iso
Running: rmdir "/mnt/Debian"/*.iso
Running: cp "/etc/apt/sources.list.net" "/etc/apt/sources.list"
Running: apt-get update
...

Usage of the command:

$ sudo $(which mount_debian.pl)
/home/mitesh/Perl/mount_debian.pl: Please provide Dir where Debian installer iso(s) are present.
USAGE: /home/mitesh/Perl/mount_debian.pl [options] iso_dir
          -a apt_sources_dir        default  /etc/apt
          -d mount_base_dir         default  /mnt/Debian
          -g                        debug on 
          -r                        apt-get update 
          -u                        unmount 
          iso_dir                   Dir where Debian installer iso(s) are present.

PS: iso_dir is not required with -u command

The mount_debian.sh perl script is given as follows:

#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  mount_debian.pl
#
#        USAGE:  ./mount_debian.pl 
#
#  DESCRIPTION:  
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh)
#      COMPANY:  
#      VERSION:  1.0
#      CREATED:  11/07/2013 10:30:04 PM IST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

use Getopt::Std;
my $apt_sources_dir = "/etc/apt";
my $mount_point_base = "/mnt/Debian";
my $umount = 0;
my $reload = 0;
my $debug = 0;

sub usage()
{
    print STDERR "USAGE: $0 [options] <iso_dir>\n";
    print STDERR "          -a <apt_sources_dir>    apt sources dir: default  $apt_sources_dir\n";
    print STDERR "          -d <mount_base_dir>     mount point dir: default  $mount_point_base\n";
    print STDERR "          -g                      debug on \n";
    print STDERR "          -r                      apt-get update \n";
    print STDERR "          -u                      unmount \n";
    print STDERR "          <iso_dir>               Dir where Debian installer iso(s) are present.\n";
}

sub run_cmd()
{
    my $cmd = $_[0];
    print "Running: $cmd\n" if $debug;
    system("$cmd");
    my $retval = $?; 
    if ($retval != 0)
    {   
        print STDERR "Error in running: $cmd\nExit code = $retval\n";
    }   
    return ($retval);
}

sub run_cmd_get()
{
    my $cmd = $_[0];
    print "Running: $cmd\n" if $debug;
    my @outs = `$cmd`;
    my $retval = $?;
    if ($retval < 0)
    {
        print STDERR "Error in running: $cmd\nExit code = $retval\n";
        exit($retval);
    }
    chomp(@outs);
    return (@outs);
}
sub take_backup() 
{
    my $file1 = $_[0];
    my $file2 = $_[1];
    my $cmd = "cp \"$file1\" \"$file2\"";
    my $retval = &run_cmd("$cmd");
    if ($retval != 0)
    {
        print STDERR "$0: Cannot copy \"$file1\" to \"$file2\"\n";
        exit(-1);
    }
    return 1;
}
sub reload_repo()
{
    my $file1 = $_[0];
    my $file2 = $_[1];

    my $cmd = "cp \"$file1\" \"$file2\"";
    my $retval = &run_cmd($cmd);
    exit(-1) if ($retval != 0);

    $cmd = "apt-get update";
    $retval = &run_cmd($cmd);
    exit(-1) if ($retval != 0);
}

my %opts;
getopt('a:d:', \%opts);

foreach my $opt (sort keys %opts)
{
    if (!defined($opts{$opt}))
    {
        print STDERR "$0: Requires value for option '$opt'\n";
        &usage();
        exit(-1);
    }
    else 
    {
        if ($opts{$opt} =~ m/^-/) 
        {
            print STDERR "$0: Requires value for option '$opt'\n";
            &usage();
            exit(-1);
        }
    }
}
$apt_sources_dir = $opts{"a"} if (defined($opts{"a"}));
$mount_point_base = $opts{"d"} if (defined($opts{"d"}));
$debug = 1 if (defined($opts{"g"}));
$reload = 1 if (defined($opts{"r"}));
$umount = 1 if (defined($opts{"u"}));

my $apt_dvd = "$apt_sources_dir/sources.list.dvd";
my $apt_net = "$apt_sources_dir/sources.list.net";
my $apt_orig = "$apt_sources_dir/sources.list";

my $retval = 0;
my $cmd;
$retval = `whoami`;
chomp($retval);
unless ($retval eq "root")
{
    print STDERR "$0: Please run this script as 'root' user.\n";
    &usage();
    exit(-1);
}

unless ($umount)
{

if (@ARGV != 1) 
{
    print STDERR "$0: Please provide Dir where Debian installer iso(s) are present.\n";
    &usage();
    exit(-1);
}
my $iso_dir = "$ARGV[0]";
## Check for iso dir presence
unless (-d "$iso_dir") 
{
    print STDERR "$0: Please make sure the iso(s) dir '$iso_dir' is present\n";
    exit(-1);
}
print "Using iso(s) dir '$iso_dir'\n" if ($debug);

## Check for destination dir
unless (-d "$mount_point_base") 
{
    $cmd = "mkdir -p \"$mount_point_base\"";
    $retval = &run_cmd("$cmd");
    if ($retval != 0) 
    {
        print STDERR "$0: Cannot create dir '$mount_point_base'\n";
        exit(-1);
    }
}
print "Using mount point dir '$mount_point_base'\n" if ($debug);

## Taking backup of ftp/http line sources.list
my $is_backed_up = 0;
if (-f "$apt_net") 
{
    ## Take backup only when ftp / http (internet)
    $cmd = "grep -v -e \"^#\" -e \"^\$\" \"$apt_orig\" | egrep -c \"(ftp|http)://\"";
    my @nets = &run_cmd_get($cmd);
    if ($nets[0] > 0) 
    {
        $is_backed_up = &take_backup("$apt_orig", "$apt_net");
    }
}
else
{
    $is_backed_up = &take_backup("$apt_orig", "$apt_net");
}

## Get loop devices
$cmd = "ls /dev/loop[0-9]*";
my @temps = &run_cmd_get($cmd);
my %loop_devices;
my $nloop_devices = @temps;
foreach my $temp (@temps) 
{
    $loop_devices{$temp} = 1;
}
$cmd = "ls \"$iso_dir\" | grep -i \"\.iso\$\"";
@temps = &run_cmd_get($cmd);
my %iso_images;
my $niso_images = @temps;
foreach my $temp (@temps) 
{
    $iso_images{$temp} = 1;
}
$cmd = "df | awk '{print \$1}' | grep \"/dev/loop\"";
@temps = &run_cmd_get($cmd);
my %mounted_loop_devices;
my $nmounted_loop_devices = @temps;
foreach my $temp (@temps) 
{
    $mounted_loop_devices{$temp} = 1;
}

## Check for free loop devices
my $nfree_loops = $nloop_devices - $nmounted_loop_devices;
if ($niso_images > $nfree_loops)
{
    print "Less available loop devices $nfree_loops than isos $niso_images\n" if ($debug);
    my $req_loops = $niso_images - $nfree_loops; 
    if ($nmounted_loop_devices == 0) 
    {
        print "Reloading loop kernel module with extra $req_loops loop devices\n" if $debug;
        $cmd = "rmmod loop";
        $retval = &run_cmd($cmd);
        print "$retval\n";
        exit(-1) if ($retval != 0);
        $cmd = "modprobe loop max_loop=$niso_images";
        $retval = &run_cmd($cmd);
        exit(-1) if ($retval != 0);
    }
    else 
    {
        print STDERR "Please reload 'loop' kernel module. After unloading following loop devices...\n";
        foreach my $temp (sort keys %mounted_loop_devices)
        {
            print STDERR "$temp\n";
        }
        print STDERR "\nrmmod loop\n";
        my $temp = $nmounted_loop_devices + $req_loops;
        print STDERR "\nmodprobe loop max_loop=$temp\n\n";
        exit(-2);
    }
}

## Create entries in sources.list file
open(SFH, ">$apt_orig") or die("$0: Cannot write in file '$apt_orig'\n");
foreach my $iso (sort keys %iso_images)
{
    print "Mounting iso $iso ...\n" if $debug;
    my $dest_dir = "$mount_point_base/$iso";
    unless (-d "$dest_dir") 
    {
        $cmd = "mkdir -p \"$dest_dir\"";
        $retval = &run_cmd($cmd);
        exit(-1) if ($retval != 0);
    }
    $cmd = "df \"$dest_dir\" | grep -c \"^/dev/loop.*\.iso\$\"";
    my @mounts = &run_cmd_get($cmd); 
    if ($mounts[0] == 0) ## Mount only if not mounted
    {
        $cmd = "mount -o loop,ro \"$iso_dir/$iso\" \"$dest_dir\"";
        $retval = &run_cmd($cmd);
        exit(-1) if ($retval != 0);

        ## read distro version dir in dists/
        $cmd = "ls -l \"$dest_dir/dists\" | grep \"^d\" | awk '{print \$(NF)}' | head -1";
        my $version = `$cmd`;
        if (defined($version) and ($version ne ""))
        {
            $cmd = "ls -l \"$dest_dir/dists\"/*/ | grep \"^d\" | sort -u | awk '{print \$(NF)}' | awk '{sec=sec\" \"\$1} END{print sec}'";
            my $sections = `$cmd`;
            if (defined($sections))
            {
                chomp($sections);
                chomp($version);
                print SFH "deb file://$dest_dir $version $sections\n";
            }
        }
    }
}
print SFH "\n## Automatically generated by $0 ##\n";
close(SFH);
print "Total $niso_images iso(s) mounted successfully.\n" if $debug;

## Reload repository if sources.list is updated
if ($is_backed_up and $reload)
{
    &reload_repo("$apt_orig", "$apt_dvd");
}
exit(0);
}
#######################################
## umount code                       ##
#######################################

$cmd = "umount \"$mount_point_base\"/*.iso";
$retval = &run_cmd($cmd);
exit(-1) if ($retval != 0);
$cmd = "rmdir \"$mount_point_base\"/*.iso";
$retval = &run_cmd($cmd);
exit(-1) if ($retval != 0);
if ($reload)
{
    &reload_repo("$apt_net", "$apt_orig");
}
exit(0);

PS: The above script can be used with any Debian Package Management related distros like Ubuntu, Linux Mint, etc.

Command Line Dictionary : meaning of


If we have only console, and we want to quickly see meaning of some word. Then we can use following perl script to get dictionary meaning of a word.
It uses perl, curl and html2text.

The source code of meaning_of.pl is :

#!/usr/bin/perl -w

## Search the dict.org

use strict;
use warnings;

sub print_usage() 
{
    print STDERR "USAGE: $0 <query>\n";
}

if (@ARGV < 1)
{
    &print_usage();
    exit(-1);
}

my $query = "$ARGV[0]";
$query =~ s/ /\%20/g;

my $cmd = "curl -# -A \"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\" -d \"Form=Dict1&Query=${query}&Strategy=*&Database=english\" \"http://www.dict.org/bin/Dict\" | html2text 2>/dev/null";
#system($cmd);
#exit($?);

open(MOFH, "$cmd | ") or die("$0: cannot execute: $cmd\n");

my $skip_lines = 10; # skip first 10 lines
my $line;
while ($line = <MOFH>)
{
    --$skip_lines;
    next if ($skip_lines > 0);
    chomp($line);
    print "$line\n";
}
close(MOFH);

exit(0);

Sample run of above perl script :

$ meaning_of.pl happiness

######################################################################## 100.0%
===============================================================================
4 definitions found for happiness
From The_Collaborative_International_Dictionary_of_English_v.0.48:

  Happiness \Hap"pi*ness\, n. [From Happy.]
     1. Good luck; good fortune; prosperity.
        [1913 Webster]

              All happiness bechance to thee in Milan! --Shak.
        [1913 Webster]

     2. An agreeable feeling or condition of the soul arising from
        good fortune or propitious happening of any kind; the
        possession of those circumstances or that state of being
        which is attended with enjoyment; the state of being
        happy; contentment; joyful satisfaction; felicity;
        blessedness.
        [1913 Webster]

     3. Fortuitous elegance; unstudied grace; -- used especially
        of language.
        [1913 Webster]

              Some beauties yet no precepts can declare,
              For there's a happiness, as well as care. --Pope.

     Syn: Happiness, Felicity, Blessedness, Bliss.

     Usage: Happiness is generic, and is applied to almost every
            kind of enjoyment except that of the animal appetites;
            felicity is a more formal word, and is used more
            sparingly in the same general sense, but with elevated
            associations; blessedness is applied to the most
            refined enjoyment arising from the purest social,
            benevolent, and religious affections; bliss denotes
            still more exalted delight, and is applied more
            appropriately to the joy anticipated in heaven.
            [1913 Webster]

                  O happiness! our being's end and aim! --Pope.
            [1913 Webster]

                  Others in virtue place felicity,
                  But virtue joined with riches and long life;
                  In corporal pleasures he, and careless ease.
                                                    --Milton.
            [1913 Webster]

                  His overthrow heaped happiness upon him;
                  For then, and not till then, he felt himself,
                  And found the blessedness of being little.
                                                    --Shak.
            [1913 Webster]
From WordNet_(r)_3.0_(2006):

  happiness
      n 1: state of well-being characterized by emotions ranging from
           contentment to intense joy [syn: happiness, felicity]
           [ant: unhappiness]
      2: emotions experienced when in a state of well-being [ant:
         sadness, unhappiness]
From Moby_Thesaurus_II_by_Grady_Ward,_1.0:

  117 Moby Thesaurus words for "happiness":
     Easy Street, acceptance, affluence, appropriateness, beatification,
     beatitude, becomingness, bed of roses, bewitchment, blessedness,
     bliss, blissfulness, blitheness, blithesomeness, brightness, cheer,
     cheerfulness, cheeriness, cheery vein, civility, cloud nine,
     clover, comfort, composure, content, contentedness, contentment,
     decency, decorousness, decorum, delectation, delight, ease,
     easy circumstances, ecstasy, ecstatics, elation, enchantment,
     enjoyment, entire satisfaction, eupeptic mien, euphoria,
     exaltation, exhilaration, exuberance, felicity, fitness,
     fittingness, fleshpots, fulfillment, gaiety, geniality,
     genteelness, gentility, gladness, gladsomeness, glee, good cheer,
     gracious life, gracious living, heaven, high spirits, hopefulness,
     intoxication, jollity, joy, joyance, joyfulness, joyousness,
     jubilation, lap of luxury, life of ease, loaves and fishes, luxury,
     meetness, optimism, overhappiness, overjoyfulness, paradise,
     peace of mind, pleasantness, pleasure, properness, propriety,
     prosperity, prosperousness, radiance, rapture, ravishment,
     reconcilement, reconciliation, resignation, rightness,
     rosy expectation, sanguine humor, sanguineness, satisfaction,
     security, seemliness, seventh heaven, success, suitability,
     sunniness, sunshine, the affluent life, the good life,
     thriving condition, transport, unalloyed happiness,
     upward mobility, urbanity, velvet, weal, wealth, welfare,
     well-being, winsomeness


From The_Devil's_Dictionary_(1881-1906):

  HAPPINESS, n.  An agreeable sensation arising from contemplating the
  misery of another.

===============================================================================
      Questions or comments about this site? Contact webmaster@dict.org

Mount/Unmount USB pendrive/USB Harddisk


We have seen sometimes automounting of external drives(USB Pendrive/USB harddisk) work and sometimes it simply does not work. The pain increase when there are multiple partitions in the external drive. To resolve this issue, I have written a perl script to mount/unmount multiple partitions.

The following perl script is useful in following cases:
1. Mounting/Unmounting(-u flag for unmounting) partitions in external drives.
2. Mounting/Unmounting partitions of internal drives too (-d , to (mount to)/(unmount from) any specific location).
3. This script also recognizes single vfat(FAT32) partition(When filesystem was created across the entire device: please refer mkfs.vfat -I) pen-drive too.
4. Others (if you find anything else, please comment 🙂 )

#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  mount_usb_disks.pl
#
#        USAGE:  ./mount_usb_disks.pl 
#
#  DESCRIPTION:  Mount USB disks or pendrive
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
#      COMPANY:  Yahoo Inc, India
#      VERSION:  1.0
#      CREATED:  02/22/2012 05:37:54 PM IST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

use Getopt::Std;
my $mount_point_base = "/mnt/usb_disks";
my $umount = 0;

sub usage()
{
    print STDERR "USAGE: $0 [options] \n";
    print STDERR "          -d <mount_base_dir>     mount point dir: default  $mount_point_base\n";
    print STDERR "          -u                      unmount \n";
}

sub run_cmd()
{
    my $cmd = $_[0];
    print "Running: $cmd\n";
    system("$cmd");
    my $retval = $?;
    if ($retval < 0)
    {
        print STDERR "Error in running: $cmd\n$retval\n";
    }
    return ($retval);
}

sub run_cmd_get()
{
    my $cmd = $_[0];
    print "Running: $cmd\n";
    my @outs = `$cmd`;
    my $retval = $?;
    if ($retval < 0)
    {
        print STDERR "Error in running: $cmd\n$retval\n";
        exit($retval);
    }
    chomp(@outs);
    return (@outs);
}

my %opts;
getopt('d:', \%opts);

foreach my $opt (sort keys %opts)
{
    if (!defined($opts{$opt}))
    {   
        print STDERR "$0: Requires value for option '$opt'\n";
        &usage();
        exit(-1);
    }   
}
if (defined($opts{"d"}))
{
    $mount_point_base = $opts{"d"};
}
if (defined($opts{"u"}))
{
    $umount = 1;
}

my $retval = 0;
my $cmd;
$retval = `whoami`;
chomp($retval);
unless ($retval eq "root")
{
    print STDERR "$0: Please run this script as 'root' user.\n";
    &usage();
    exit(-1);
}
unless ($umount)
{
    print "Mounting on $mount_point_base\n";
    unless (-d "$mount_point_base") 
    {
        $retval = &run_cmd("mkdir -p $mount_point_base");
        exit($retval) if ($retval < 0);
    }

    my @temps = &run_cmd_get("mount | awk '{print \$1}' | grep \"^/dev/\"");
    my %mounted_devs;
    foreach my $temp (@temps)
    {
        $mounted_devs{$temp} = 1;
        $temp =~ s/\/sd([a-z]).*/\/sd$1/;
        $mounted_devs{$temp}++;
    }
    ## Take care of swap
    @temps = &run_cmd_get("cat /proc/swaps | awk '{print \$1}' | grep \"^/dev/\"");
    foreach my $temp (@temps)
    {
        $mounted_devs{$temp} = 1;
        $temp =~ s/\/sd([a-z]).*/\/sd$1/;
        $mounted_devs{$temp}++;
    }
    my %unmounted_devs;
    my $total = 0;
    @temps = &run_cmd_get("ls /dev/sd*");
    foreach my $temp (@temps)
    {
        next if (defined($mounted_devs{$temp}));
        ## Take care of logical partition, which cannot be mounted
        my @outs = &run_cmd_get("fdisk -s $temp");
        $retval = $outs[0];
        next if ($retval <= 1);      
        $unmounted_devs{$temp} = 1;
        $temp =~ s/\/sd([a-z]).*/\/sd$1/;
        if (defined($unmounted_devs{$temp}))
        {
            delete($unmounted_devs{$temp});
            $total--;
        }
        $total++;
    }
    if ($total == 0)
    {
        print "$0: No partition to mount.\nexiting...\n";
        exit(0);
    }

    print "\n--------------------------------------------\n";
    print "Following partitions are not mounted...\n";
    print "--------------------------------------------\n";
    foreach my $temp (sort keys %unmounted_devs) 
    {
        print "$temp\n";
    }
    print "--------------------------------------------\n";

    ## Now we can mount these
    foreach my $temp (sort keys %unmounted_devs)
    {
        my $mount_dir = $temp;
        $mount_dir =~ s/^\/dev\//$mount_point_base\//;
        print "Mounting $temp -> $mount_dir\n";
        unless (-d "$mount_dir")
        {
            $retval = &run_cmd("mkdir -p $mount_dir");
            exit($retval) if ($retval < 0);
        }

        $cmd = "mount $temp $mount_dir";
        $retval = &run_cmd("$cmd");
        if ($retval < 0)
        {
            print STDERR "!!!Cannot mount $temp on $mount_dir\n";
        }
    }
}
else
{
    unless ($mount_point_base =~ m/^\//) 
    {
        $retval = `pwd`;
        chomp($retval);
        $mount_point_base = "$retval/$mount_point_base";
    }
    print "Unmounting from $mount_point_base\n";
    $cmd = "mount | awk -F \" on \" '{print \$2}' | awk -F \" type \" '{print \$1}' | grep \"$mount_point_base\"";
    my @temps = &run_cmd_get("$cmd");
    if (@temps == 0)
    {
        print "$0: No partition to unmount.\nexiting...\n";
        exit(0);
    }
    print "\n--------------------------------------------\n";
    print "Following directories are mounted...\n";
    print "--------------------------------------------\n";
    foreach my $temp (@temps)
    {
        print "$temp\n";
    }
    print "--------------------------------------------\n";

    foreach my $temp (@temps)
    {
        $cmd = "umount $temp";
        $retval = &run_cmd("$cmd");
        if ($retval < 0)
        {
            print STDERR "!!!Cannot umount $temp\n";
        }
        else
        {
            &run_cmd("rmdir $temp");       # delete dir if empty
        }
    }
}
exit(0);

Video Cutter V2: Video Cutting Using Mencoder


I have upgraded the Video Cutter program. Now it has 2 more features:

1. Strict Mode (-s flag): In this mode, strict monotonously increasing order of times must be given in the configuration (default: video_cutter.conf) file.
2. Joining Split Videos (-j flag): When this flag is given with the command, it does join the split video files into a single video file.

Here is the updated version of the earlier perl script:

#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  video_cutter.pl
#
#        USAGE:  ./video_cutter.pl [options] <input_video_file>
#
#  DESCRIPTION:  
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
#      VERSION:  2.0
#      CREATED:  02/12/2011 03:57:55 PM IST
#===============================================================================

use strict;
use warnings;

use Getopt::Std;

sub usage()
{
    print STDERR "USAGE: $0 [options] <input_video_file>\n";
    print STDERR "          -c <conf_file>    default  /base_dir/input_video_file/video_cutter.conf\n";
    print STDERR "                            Start_time(hh:mm:ss),End_time(hh:mm:ss)\n\n";
    print STDERR "          -o <out_dir>      default  /base_dir/input_video_file/\n";
    print STDERR "          -s                strict format check for conf files     [default: no checking]\n";
    print STDERR "          -j                Join output splits into one video file [default: no joining]\n";
}

sub hms_to_seconds()
{
    my $end_sec = 0;
    my ($h, $m, $s) = split(/:/, $_[0]);
    $s = defined($s) ? $s : 0;
    $end_sec += $s;
    $m = defined($m) ? $m : 0;
    $end_sec += (60 * $m);
    $h = defined($h) ? $h : 0;
    $end_sec += (60 * 60 * $h);
    return($end_sec);
}

sub check_times_in_file()
{
    my $conf_file = $_[0];
    open(FH, "$conf_file") or die("$0: Cannot open '$conf_file'\n");
    my $line;
    my $nline = 0;
    my $prev_end_sec = -1;
    while ($line = <FH>)
    {
        chomp($line);
        ++$nline;
        next if ($line =~ m/^#/);
        my ($start_time, $end_time) = split(/,/, $line);
        if (!defined($end_time))
        {
            print STDERR "$0: End time(HH:MM:SS) is not present in line no $nline: $line\n";
            close(CFH);
            return;
        }
        my ($h, $m, $s) = split(/:/, $start_time);
        if (!defined($s))
        {
            print STDERR "$0: Start time is not in format (HH:MM:SS) line no $nline: $line\n";
            close(CFH);
            return;
        }
        ($h, $m, $s) = split(/:/, $end_time);
        if (!defined($s))
        {
            print STDERR "$0: End time is not in format (HH:MM:SS) line no $nline: $line\n";
            close(CFH);
            return;
        }

        my $start_sec = &hms_to_seconds($start_time);
        my $end_sec = &hms_to_seconds($end_time);
        if ($start_sec >= $end_sec)
        {
            print STDERR "$0: $start_sec >= $end_sec in line no $nline: $line\n";
            close(CFH);
            return;
        }
        if ($prev_end_sec >= $start_sec)
        {
            print STDERR "$0: $prev_end_sec >= $start_sec in line no $nline: $line and prev line\n";
            close(CFH);
            return;
        }
        $prev_end_sec = $end_sec;
    }
    close(FH);
    return ($nline);
}

my %opts;
getopt('o:c:', \%opts);

foreach my $opt (sort keys %opts)
{
    if (!defined($opts{$opt}))
    {
        print STDERR "$0: Requires value for option '$opt'\n";
        &usage();
        exit(-1);
    }
}

if (@ARGV != 1)
{
    &usage();
    exit(-1);
}

my $input_video_file = "$ARGV[0]";
my $out_dir = `dirname $input_video_file`;
chomp($out_dir);
my $conf_file = "$out_dir/video_cutter.conf";
my $strict_checking = 0;
my $join_outputs = 0;
my $out_video_files = "";

if (defined($opts{"c"}))
{
    $conf_file = $opts{"c"};
}
if (defined($opts{"o"}))
{
    $out_dir = $opts{"o"};
}
if (defined($opts{"s"}))
{
    $strict_checking = 1;
}
if (defined($opts{"j"}))
{
    $join_outputs = 1;
}

unless (-f "$input_video_file")
{
    print STDERR "$0: Input video file '$input_video_file' is not present\n";
    exit(-1);
}
unless (-f "$conf_file")
{
    print STDERR "$0: split conf file '$conf_file' is not present\n";
    exit(-1);
}
unless (-d "$out_dir")
{
    print STDERR "$0: out dir '$out_dir' is not present\n";
    exit(-1);
}
unless (-w "$out_dir")
{
    print STDERR "$0: out dir '$out_dir' is not writable\n";
    exit(-1);
}

my $mencoder = "/usr/local/bin/mencoder";
unless (-x $mencoder)
{
    $mencoder = "/usr/bin/mencoder";
}
unless (-x $mencoder)
{
    print STDERR "$0: please install mencoder\n";
    print STDERR "sudo apt-get install mencoder\n";
    exit(-1);
}

open(CFH, "$conf_file") or die("$0: Cannot open '$conf_file'\n");
my $line;
my $nline = 0;
my $nsplit = 0;
my $split_name = `basename $input_video_file`;
chomp($split_name);
$split_name =~ s/\.[^.]*$//;
my $split_ext = $input_video_file;
$split_ext =~ s/.*\.([^.]*)$/$1/;
my $success = 0;

if ($strict_checking == 1)
{
    print "Strict Mode\n";
    my $retval = &check_times_in_file($conf_file);
    if (!defined($retval))
    {
        print STDERR "$0: Problem in conf file \"$conf_file\"\n";
        exit(-1);
    }
}
while ($line = <CFH>)
{
    chomp($line);
    $nline++;
    next if ($line =~ m/^#/);
    my ($start_time, $end_time) = split(/,/, $line);
    next if (!defined($end_time));
    my $start_sec = &hms_to_seconds($start_time);
    my $end_sec = &hms_to_seconds($end_time);
    if ($start_sec >= $end_sec)
    {
        print STDERR "$0: $start_sec >= $end_sec\n";
        print STDERR "    $start_time >= $end_time ... skipping for line no $nline ...\n";
        next;
    }
    $end_sec -= $start_sec;
    my $cmd = sprintf("%s -ss %d -endpos %d -ovc copy -oac copy -o %s/%s_%03d.%s %s", 
            $mencoder, $start_sec, $end_sec, $out_dir, $split_name, $nsplit,
            $split_ext, $input_video_file);
    print "\n\n";
    print "-" x 80 . "\n";;
    print "$cmd\n";
    system("$cmd");
    if ($? != 0)
    {
        print STDERR "$0: failed to create $nsplit split for line no $nline\n";
        print STDERR "\t$cmd\n";
    }
    else
    {
        print STDOUT "Created $nsplit split for line $nline\n";
        $out_video_files .= sprintf(" %s/%s_%03d.%s", $out_dir, $split_name, $nsplit, $split_ext);
        $success++;
    }
    print "-" x 80 . "\n";;
    $nsplit++;
}

close(CFH);

print "\n";
print "=" x 80 . "\n";;
printf("Total lines = %d,   Success = %d/%d,  Failure = %d/%d\n",
        $nline, $success, $nsplit,
        $nsplit - $success, $nsplit);
print "=" x 80 . "\n";;

if ($join_outputs == 1)
{
    if ($success < 1)
    {
        print STDERR "$0: failed to join video files.\n";
        exit(-1);
    }
    my $joined_video_file = sprintf("%s/%s_joined.%s", $out_dir, $split_name, $split_ext);
    my $cmd = sprintf("%s -ovc copy -oac copy -o %s %s", 
            $mencoder, $joined_video_file, $out_video_files);
    print "\n\n";
    print "-" x 80 . "\n";;
    print "Joining Video Files into $joined_video_file\n";
    print "-" x 80 . "\n";;
    print "$cmd\n";
    system("$cmd");
    if ($? != 0)
    {
        print STDERR "$0: failed to create joined video file $joined_video_file\n";
        print STDERR "\t$cmd\n";
    }
    else
    {
        print STDOUT "Created joined video file $joined_video_file\n";
    }
    print "-" x 80 . "\n";;
}

exit(0);

Video Cutter: Video Cutting using Mencoder


I have written a perl script, then can split/cut parts from a video file.

#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  video_cutter.pl
#
#        USAGE:  ./video_cutter.pl [options] <input_video_file>
#
#  DESCRIPTION:  
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
#      VERSION:  1.0
#      CREATED:  06/26/2011 03:57:55 PM IST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

use Getopt::Std;

sub usage()
{
   print STDERR "USAGE: $0 [options] <input_video_file>\n";
   print STDERR "          -c <conf_file>    default  /base_dir/input_video_file/video_cutter.conf\n";
   print STDERR "                            Start_time(hh:mm:ss),End_time(hh:mm:ss)\n\n";
   print STDERR "          -o <out_dir>      default  /base_dir/input_video_file/\n";
}

sub hms_to_seconds()
{
   my $end_sec = 0;
   my ($h, $m, $s) = split(/:/, $_[0]);
   $s = defined($s) ? $s : 0;
   $end_sec += $s;
   $m = defined($m) ? $m : 0;
   $end_sec += (60 * $m);
   $h = defined($h) ? $h : 0;
   $end_sec += (3600 * $h);
   return($end_sec);
}

my %opts;
getopt('o:c:', \%opts);

foreach my $opt (sort keys %opts)
{
   if (!defined($opts{$opt}))
   {
       print STDERR "$0: Requires value for option '$opt'\n";
       &usage();
       exit(-1);
   }
}

if (@ARGV != 1)
{
   &usage();
   exit(-1);
}

my $input_video_file = "$ARGV[0]";
my $out_dir = `dirname $input_video_file`;
chomp($out_dir);
my $conf_file = "$out_dir/video_cutter.conf";

if (defined($opts{"c"}))
{
   $conf_file = $opts{"c"};
}
if (defined($opts{"o"}))
{
   $out_dir = $opts{"o"};
}

unless (-f "$input_video_file")
{
   print STDERR "$0: Input video file '$input_video_file' is not present\n";
   exit(-1);
}
unless (-f "$conf_file")
{
   print STDERR "$0: split conf file '$conf_file' is not present\n";
   exit(-1);
}
unless (-d "$out_dir")
{
   print STDERR "$0: out dir '$out_dir' is not present\n";
   exit(-1);
}
unless (-w "$out_dir")
{
   print STDERR "$0: out dir '$out_dir' is not writable\n";
   exit(-1);
}

my $mencoder = "/usr/local/bin/mencoder";
unless (-x $mencoder)
{
   $mencoder = "/usr/bin/mencoder";
}
unless (-x $mencoder)
{
   print STDERR "$0: please install mencoder\n";
   print STDERR "sudo apt-get install mencoder\n";
   exit(-1);
}

open(CFH, "$conf_file") or die("$0: Cannot open '$conf_file'\n");
my $line;
my $nline = 0;
my $nsplit = 0;
my $split_name = `basename $input_video_file`;
chomp($split_name);
$split_name =~ s/\.[^.]*$//;
my $split_ext = $input_video_file;
$split_ext =~ s/.*\.([^.]*)$/$1/;
my $success = 0;
while ($line = <CFH>)
{
   chomp($line);
   $nline++;
   next if ($line =~ m/^#/);
   my ($start_time, $end_time) = split(/,/, $line);
   next if (!defined($end_time));
   my $start_sec = &hms_to_seconds($start_time);
   my $end_sec = &hms_to_seconds($end_time);
   if ($start_sec >= $end_sec)
   {
       print STDERR "$0: $start_sec >= $end_sec\n";
       print STDERR "    $start_time >= $end_time ... skipping for line no $nline ...\n";
       next;
   }
   $end_sec -= $start_sec;
   my $cmd = sprintf("%s -ss %d -endpos %d -ovc copy -oac copy -o %s/%s_%03d.%s %s",
           $mencoder, $start_sec, $end_sec, $out_dir, $split_name, $nsplit,
           $split_ext, $input_video_file);
   print "\n\n";
   print "-" x 80 . "\n";;
   print "$cmd\n";
   system("$cmd");
   if ($? != 0)
   {
       print STDERR "$0: failed to create $nsplit split for line no $nline\n";
       print STDERR "\t$cmd\n";
   }
   else
   {
       print STDOUT "Created $nsplit split for line $nline\n";
       $success++;
   }
   print "-" x 80 . "\n";;
   $nsplit++;
}

close(CFH);

print "\n";
print "=" x 80 . "\n";;
printf("Total lines = %d,   Success = %d/%d,  Failure = %d/%d\n",
       $nline, $success, $nsplit,
       $nsplit - $success, $nsplit);
print "=" x 80 . "\n";;

exit(0);

Please place the above perl script (video_cutter.pl) in any directory present in $PATH.

Sample Run:

Usage of the above script.

$ video_cutter.pl 
USAGE: /home/mitesh/Programming/Perl/WCS/video_cutter.pl [options] 
         -c     default  /base_dir/input_video_file/video_cutter.conf
                           Start_time(hh:mm:ss),End_time(hh:mm:ss)

         -o       default  /base_dir/input_video_file/

Content of a sample config file, specifying the split timings.
This will create 3 splits, of 0s-90s, 140s-210s, and 240s-End.

$ cat test_video.conf 
00:00:00,00:01:30
00:02:20,00:03:30
00:04:00,59:59:00

Now, it will create the three split files in ~/Video/test/ directory.

$ video_cutter.pl -c test_video.conf -o ~/Video/test test_video.vob 


--------------------------------------------------------------------------------
/usr/local/bin/mencoder -ss 0 -endpos 90 -ovc copy -oac copy -o /home/mitesh/Video/test/test_video_000.vob test_video.vob
MEncoder 1.0rc4-4.4.5 (C) 2000-2010 MPlayer Team
...
...
...
Created 2 split for line 3
--------------------------------------------------------------------------------

================================================================================
Total lines = 3,   Success = 3/3,  Failure = 0/3
================================================================================
$ ls -l ~/Video/test/*.vob
-rw-r--r-- 1 mitesh mitesh   7519672 Jun 27 00:31 /home/mitesh/Video/test/test_video_000.vob
-rw-r--r-- 1 mitesh mitesh   5844598 Jun 27 00:31 /home/mitesh/Video/test/test_video_001.vob
-rw-r--r-- 1 mitesh mitesh 570855360 Jun 27 00:30 /home/mitesh/Video/test/test_video_002.vob

Find Files Created Between 2 Times


In order to find files created between two times (start hour and end hour). The required hours are hours from current time. For example,

Current time = 2 PM = 14:00

If you want file created between 9 AM and 12 PM today, the start hour and end hour are:

Start Hour = (14 – 9) = 5
End Hour = (14 – 12) = 2

Hence required command is:

$  ./find_files_between_times.pl /path/to/dir 5 2

The Perl script which does this is given below:-

#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  find_files_between_times.pl
#
#        USAGE:  ./find_files_between_times.pl <dir> <start_hour> <end_hour>
#
#  DESCRIPTION:  
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
#      COMPANY:  Yahoo Inc, India
#      VERSION:  1.0
#      CREATED:  11/13/2009 10:00:02 PM IST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

if (@ARGV != 3)
{
    print STDERR "Usage: $0 <dir> <start_hour> <end_hour>\n";
    exit(-1);
}

my $dir = $ARGV[0];
## Calculate current_hour - given_hour
#my $start_time = `/bin/date "+\%H"`;
my $start_time = $ARGV[1];
#chomp($start_time);
my $end_time = $ARGV[2];
$end_time = time - ($end_time * 60 * 60);
#$end_time = $start_time - $end_time;
#$start_time = $start_time - $ARGV[0];

if ($start_time > $end_time)
{
    ($start_time, $end_time) = ($end_time, $start_time);
}

my $cmd = "find $dir -ctime -$start_time";
print "Running $cmd\n";
my @files = `$cmd`;
foreach my $file (@files) # (`find $dir -ctime $start_time`)
{
    chomp($file);
    my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
                           $atime,$mtime,$ctime,$blksize,$blocks) 
        = stat($file);

    if ($ctime > $end_time)
    {
        next;
    }
    print "$file\n";
}


exit(0);

Editing Very Very Large File


Suppose we want to do changes in few lines in a very very large file. It is not possible to open such a big file(say size in GBs > RAM+Swap size) in a editor. Even sed/awk takes very long time, because they do pattern matching if mentioned on every line, otherwise, we can do one line editing with a line number. I have written a Perl Script to edit multiple lines independently. It uses sed commands to edit a line.

Format of Config file is:
line_number:sed_command

#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  ed_large_file.pl
#
#        USAGE:  ./ed_large_file.pl <config_file> <file_name> [overwrite}
#
#  DESCRIPTION:  Edit very[ very] large file
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
#      VERSION:  1.0
#      CREATED:  Thursday 25 June 2009 02:32:37  IST IST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

if (@ARGV < 2)
{
    print STDERR "$0: <config_file> <file_name> [overwrite]\n";
    print STDERR "!!!Be careful while using [overwrite] option,\n";
    print STDERR "because original file will be deleted.\n";
    exit(-1);
}

my $conf_file = $ARGV[0];
my $large_file = $ARGV[1];
my $overwrite = 0;
if (@ARGV >= 3 && $ARGV[2] eq "overwrite")
{
    $overwrite = 1;
}

my $temp_file = `dirname $large_file`;
chomp($temp_file);
if ($temp_file eq "" || (!(-d $temp_file)))
{
    print STDERR "$0: Cannot find dirname for temporary file.\n";
    print STDERR "Please check path of file '$large_file'\n";
    exit(-1);
}

$temp_file = $temp_file . "/temp";
print "Temporary file is '$temp_file'\n";

## Read config file
print "Reading config file '$conf_file'\n";
open(CFH, "$conf_file") or die("Cannot read Config file '$conf_file'\n");
my $line;
my %lineno_sedcmd;
while ($line = <CFH>)
{
    chomp($line);
    my ($lineno, $sedcmd) = split /:/, $line, 2;
    if (defined($sedcmd))
    {
        $lineno_sedcmd{$lineno} = $sedcmd;
        print "$lineno  $lineno_sedcmd{$lineno}\n";
        # Verifying sedcmd before running it;
        # it gives a chance to reedit config file
        my $cmd = "echo \"Mitesh Singh Jat\" | sed '$sedcmd' 1> /dev/null 2>&1";
        if (!(system($cmd) == 0))
        {
            print STDERR "$0: sed command '$sedcmd' for line '$lineno'";
            print STDERR "is having error. Please recheck with \$ man sed\n";
            close(CFH);
            exit(-1);
        }
    }
}
close(CFH);

my @line_nos;
foreach (sort keys (%lineno_sedcmd))
{
    push(@line_nos, $_);
}

## Open large file
open(LFH, "$large_file") or die("$0: Cannot open file '$large_file'");
## Temporary File 
open(OFH, ">$temp_file") or die("$0: Cannot create temporary file '$temp_file'");
my $nline = 0;
my $i = 0;
my $end_idx = @line_nos - 1;
print "Processing...";
while ($line = <LFH>)
{
    ++$nline;
    if ($line_nos[$i] == $nline)       # now edit
    {
        ++$i;   # This config line is over
        if ($i > $end_idx)
        {
            $i = $end_idx;
        }
        chomp($line);
        my $cmd = "echo \"$line\" | sed '$lineno_sedcmd{$nline}'";
        #print "$cmd\n";
        my $out_line = `$cmd`;
        print OFH "$out_line";
        print " $nline"; #sleep 1; # to see progress :)
    }
    else
    {
        print OFH "$line";
    }
}

print "\n";

close(OFH);
close(LFH);

if ($overwrite == 0)
{
    print "done\n";
    exit(0);
}

## Overwite original file by deleting it and moving temp
print "Overwriting...\n";
my $cmd = "rm -f $large_file \&\& mv $temp_file $large_file";
print "$cmd\n";
system($cmd) == 0 
    or die("Problem in overwriting. '$cmd' failed: $?\n");
print "done\n";    
exit(0);

Sample Run:

–(0 : 618)> ./ed_large_file.pl
./ed_large_file.pl:
<config_file> <file_name> [overwrite]
!!!Be careful while using [overwrite] option,

because original file will be deleted.

–(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)–
–(255 : 619)> cat large_file.txt
Shree Ganeshay Namah
Shri Bharat Singh Jat
Smt Amita Jat
Mitesh Jat
Shikha Jat
Shilpa Jat
This is garbage line. Please delete it.
–(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)–
–(0 : 620)> cat large_file.conf
1:s/^.*$/!!&!!/
4:s/ / Singh /
7:/.*/d
–(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)–
–(0 : 621)> ./ed_large_file.pl large_file.conf large_file.txt
Temporary file is ‘./temp’
Reading config file ‘large_file.conf’
1 s/^.*$/!!&!!/
4 s/ / Singh /
7 /.*/d
Processing… 1 4 7
done
–(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)–
–(0 : 622)> cat ./temp
!!Shree Ganeshay Namah!!
Shri Bharat Singh Jat
Smt Amita Jat
Mitesh Singh Jat
Shikha Jat
Shilpa Jat
–(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)–
–(0 : 623)> ./ed_large_file.pl large_file.conf large_file.txt overwrite
Temporary file is ‘./temp’
Reading config file ‘large_file.conf’
1 s/^.*$/!!&!!/
4 s/ / Singh /
7 /.*/d
Processing… 1 4 7
Overwriting…
rm -f large_file.txt && mv ./temp large_file.txt
done
–(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)–
–(0 : 624)> cat large_file.txt
!!Shree Ganeshay Namah!!
Shri Bharat Singh Jat
Smt Amita Jat
Mitesh Singh Jat
Shikha Jat
Shilpa Jat
–(mitesh@roundduck-lm)-(~/Programming/Perl/Editing_Large_Files)–
–(0 : 625)>

Backup Using rsync


There are many backup tools, but most are not as configurable as
rsync command. But still we may want more easiness to use rsync.
Therefore, I have written a Perl Script to use rsync for backing up
as many directories as you want. Here is a Perl script:

#!/usr/bin/perl 
#===============================================================================
##         FILE:  rsync_backup.pl
##        USAGE:  ./rsync_backup.pl [output_dir]
##  DESCRIPTION:
##      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
#      VERSION:  1.0#      CREATED:  Saturday 28 March 2009 07:36:54  IST IST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

my $rsync_include = "rsync_include.conf";
my $rsync_exclude = "rsync_exclude.conf";
my $out_dir = "/media/FreeAgent Drive";
if (@ARGV >= 1)
{
    $out_dir = $ARGV[0];
}

unless (-f $rsync_include)
{
    print STDERR "$0: Include config file $rsync_include is not present.";
    exit(-1);
}

my $exclude_option = "--exclude-from=$rsync_exclude";

unless (-f $rsync_exclude)
{
    print STDERR "$0: exclude config file $rsync_exclude is not present.";
    $exclude_option = "";
}

unless (-d $out_dir)
{
    print STDERR "$0: $out_dir Destination dir does not exists.\n";
    exit(-1);
}

$out_dir =~ s/ /\\ /g;

open(FH, "$rsync_include") or die("$0: Cannot open $rsync_include\n");
my $line;
my $nlines = 0;
while ($line = <FH>)
{
    my $command;
    my $options = "";
    chomp($line);
    ++$nlines;
     if ($line =~ /^#/) # skip comments
     {
          next;
     }
     my @fields = split(//, $line); # this junk char is Ctrl-X
     if (@fields < 3)
     {
          print "Not enough arguments in line $nlines\n";
          next;
     }
     if ($fields[2] =~ /^[Yy]/)  # sync
     {
          $options .= " --delete --delete-excluded";
     }
     if (defined($fields[3]))
     {
          $options .= " $fields[3]";
     }

     $fields[0] =~ s/<home>/\/home\/mitesh/;
     $fields[1] =~ s/<home>/\/home\/mitesh/;
     $fields[0] =~ s/<out_dir>/$out_dir/g;
     $fields[1] =~ s/<out_dir>/$out_dir/g;

     $command = "rsync -av $fields[0] $fields[1] $options ";
     system($command) == 0  or die("$0: Error in running\n$command\n$!\n");
}
close(FH);
exit(0);

There are 2 configuration files, I have used for this script. Namely
1. rsync_include.conf
2. rsync_exclude.conf

Please place these 2 files in the directory, from where you are going
to run this script, else you can change path of these configuration
files in rsync_backup.pl .

Sample rsync_include.conf contains:
# Configuration file for backing up
#
# ^X is delimiter, which can be typed as Ctrl-V Ctrl-X
#src_folder^Xdest_folder^Xdelete_at_dest[Y/n]^Xother_rsync_options
#
## delete_at_dest =>
# y = sync // Use cautiously
# n = copy blindly
#
# Some tags that can be used:
## <home> = Home directory; change to your home directory in the script.
## <out_dir> = Common Destination Directory
#
/home/mitesh/Music^X<out_dir>^Xy^X
<home>/Documents^X<out_dir>^Xn^X
<home>/Programming^X<out_dir>^Xn^X
/home/mitesh/Videos^X<out_dir>^Xn^X
#/workspace/temp/*^X<out_dir>/temp^Xn^X
/mnt/extra/Extra/Films/*^X<out_dir>/Videos^Xn^X
/mnt/extra/Extra/Download/*^X<out_dir>/Videos^Xn^X

Sample rsync_exclude.conf contains:
.trash
Trash
Cache
.thumbnails
*.torrent

Sample run (I have placed above config files in ~/bin/):
$ cd ~/bin
$ ./rsync_backup.pl

or, if you want to use some backup directory on harddisk,
mounted on /media/disk (say, /media/disk/backup)
$ ./rsync_backup /media/disk/backup

Finding Best Linux Distribution


We can find ranking of Linux distributions (distros) at site distrowatch.com. This ranking is based on Page Hits Per Day.In order to find best Linux distro, I have written a Perl script:


#!/usr/bin/perl -w
#===============================================================================
#
# FILE: best_distro.pl
#
# USAGE: ./best_distro.pl
#
# DESCRIPTION: Finds best distro from distrowatch.com
#
# OPTIONS: ---
# REQUIREMENTS: ---
# BUGS: ---
# NOTES: ---
# AUTHOR: Mitesh Singh Jat (mitesh)
# VERSION: 1.0
# CREATED: Tuesday 04 November 2008 04:05:19 IST
# REVISION: ---
#===============================================================================

use strict;
use warnings;

my $ndistro = 1;

if (@ARGV >= 1)
{
$ndistro = $ARGV[0];
if ($ndistro > 100)
{
$ndistro = 100;
}
}

my $lynx = `which lynx`;
chomp($lynx);
if ($lynx eq "")
{
print STDERR "$0: please install lynx\n";
print STDERR "sudo apt-get install lynx\n";
exit(-1);
}

open(LYNX, "lynx -source http://distrowatch.com/ |") or die("$0: cannot open lynx: $!\n");

my $i = 1;

while ($i <= $ndistro)
{
my $line;
my $distro;
my $rank = "";
while ($line = <LYNX>)
{
chomp($line);
$line =~ s/<th class=([^>]*)>(.*?)<\/th>/$2/i;
$line =~ s/(\s+)//g;
if ($line eq "$i")
{
$rank = $line;

unless ($line = <LYNX>) {last;}
chomp($line);
$line =~ s/<td class=([^>]*)><a href=([^>]*)>(.*?)<\/a><\/td>/$3/i;
$line =~ s/(\s+)//g;
$distro = $line;

print "$rank\t$distro\n";
last;
}
}
++$i;
}

close(LYNX);

Sample runs of above program:
$ ./best_distro.pl
1 Ubuntu
$ ./best_distro.pl 5
1 Ubuntu
2 openSUSE
3 Mint
4 Fedora
5 Debian

Retrieving Date and Time from Unix Timestamp


In Unix, we can retrieve Date and Time from Timestamp by using following command:
$ date -r 1220000000
Fri Aug 29 14:23:20 IST 2008

But in Linux, there is no ‘-r’ option. Therefore, I have written a Perl script to
retrieve date and time from timestamp. Here is the script:

$ vi ~/bin/dater.pl

#!/usr/bin/perl -w

use strict;
use warnings;

my $ts = time;
if (@ARGV >= 1)
{
    $ts = $ARGV[0];
}
my ($sec, $min, $hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($ts);
++$mon;
$year+=1900;
print “$mday-$mon-$year $hour:$min:$sec\n”;


# end dater.
pl

Sample runs of above program:
$ dater.pl
15-10-2008 12:34:37
$ dater.pl 1220000000
29-8-2008 14:23:20

PS: you can change parameters in print function in the program
according to output you desire.