A few years ago, one of my friends asked me for advice. He was frustrated, mostly out of his job. I wanted to help, but he was at the other side of the globe! I couldn't give him a ready solution. But instead, I sent him my recepie of solving a problem. Here it is.
1. Identify the problem
This is the first step. Unless we identify the exact problem, with all its details, we won't be able to prepare a solution for it. If you could prepare a problem statement, not more than a few lines, that would help much to make things clear.
2. Make a list of all possible solutions
When you are aware what the problem is or what is bothering you or what is it that you are not satisfied with, think of all the possible ways in which the situation could be improved. Even if a solution looks simple, or complex, far fetched, or lengthy, do add it to your list. Include only practical solutions.
3. Choose the best solution from the list
When you know the all possible ways, choose the best one. Depends on what is best for you in that situation. Choosing the best one would require comparisons and judgement on the criteria that you have.
4. Implement the best solution that we now know
Go ahead, its time for action.
When I have a problem, I tend to think in this way. And it works for me. And who doesn't have problems in this world? Sometimes I think that we are here to solve problems. We are all problem-solvers.
Friday, December 26, 2008
Sunday, December 21, 2008
screen 'em
Some of the tasks that I do involve running commands that take way long to finish - some take a few hours, others take a couple of days. Obviously, you can't be staring at the terminal till the task is done. And if you close the terminal, the command dies away. So how to run these commands? Simply running them in background won't help, as they would be terminated when you log out.
One idea is to run them in background, and using nohup.
$ nohup my_cmd &
$ exit
This would start the command in the background in such a way that it won't be stopped even if you log out. But you won't see the output at your terminal. nohup would redirect it to a file named nohup.out
Once I start the command using nohup, there is no way I can interact with it. And I can't see the output at the terminal. Sure, there is a way if I really want to. Keep watching: $ tail -f nohup.out
A better alternative in these scenarios is to use the GNU Screen utility. It offers many useful features.
* I can start the command and leave it alone. Later, I can see how it is progressing whenever I want to.
* I can start the command from one computer, and then see how it is progressing from a different computer. So I can start the task at office, then go home, and when I find time, check how it is going.
* More than one users can share a screen. So if my colleague wants to check, he can also connect to the same screen and see the progress.
* Multiple terminal sessions can be created in a screen session. So I can keep running the command in one of them, and do something else in the other.
* Screen is very helpful when the network connection is unreliable. I would still have the task running even if connection breaks.
Enough. Tel me how do I start.
Check if a screen session is already running
$ screen -ls
Attach to a not detached session
$ screen -x
Start a new screen session
$ screen
Create a new terminal session
CTRL+a c
Toggle between two terminal sessions
CTRL+a CTRL+a
Go to the nth terminal session
CTRL+a n
Send the command character CTRL+a to a window
CTRL+a a
Detach from a screen
CTRL+a d
Terminate the screen
$ exit
man screen for more information
One idea is to run them in background, and using nohup.
$ nohup my_cmd &
$ exit
This would start the command in the background in such a way that it won't be stopped even if you log out. But you won't see the output at your terminal. nohup would redirect it to a file named nohup.out
Once I start the command using nohup, there is no way I can interact with it. And I can't see the output at the terminal. Sure, there is a way if I really want to. Keep watching: $ tail -f nohup.out
A better alternative in these scenarios is to use the GNU Screen utility. It offers many useful features.
* I can start the command and leave it alone. Later, I can see how it is progressing whenever I want to.
* I can start the command from one computer, and then see how it is progressing from a different computer. So I can start the task at office, then go home, and when I find time, check how it is going.
* More than one users can share a screen. So if my colleague wants to check, he can also connect to the same screen and see the progress.
* Multiple terminal sessions can be created in a screen session. So I can keep running the command in one of them, and do something else in the other.
* Screen is very helpful when the network connection is unreliable. I would still have the task running even if connection breaks.
Enough. Tel me how do I start.
Check if a screen session is already running
$ screen -ls
Attach to a not detached session
$ screen -x
Start a new screen session
$ screen
Create a new terminal session
CTRL+a c
Toggle between two terminal sessions
CTRL+a CTRL+a
Go to the nth terminal session
CTRL+a n
Send the command character CTRL+a to a window
CTRL+a a
Detach from a screen
CTRL+a d
Terminate the screen
$ exit
man screen for more information
Saturday, December 20, 2008
bad command or file name
Really? Is my command so bad? Then what would a good command look like?
Long gone are the days when I last saw the (in)famous error message. Most of us would have forgotten it by now. One of the blogs that I was reading today mentioned about it. And in a rhetoric manner.
Why would you want to tell someone that something they entered is bad? Or something bad has happened? Isn't that really foolish? Didn't Mom tell them: "If you can't say anything nice, don't say anything at all." At least, don't say a bad word.
A major reason why software is not easy to learn is that it doesn't give positive feedback. We learn better from positive feedback, rather than from negative feedback. Would you prefer a hired ski instructor who yells at you? Or a restaurant host who loudly announces to other patrons that your credit card was rejected? Certainly not. Then why the should software tell me that I failed?
In my opinion, to be given negative feedback by software - any software - is an insult to human. Yes, I've read the three laws of robotics, and can recite them for you even during sleep.
Forget robotics and the mean machines, but for me, to be told by software that you have failed is degrading. And the same should be for everyone. There is nothing so important inside that dumb box that you can justify degrading a human user. If you want to protect you files, do it. But do so without bothering me. It's all right to protect the computer but not at the cost of bothering the user.
If I mistype a command, with bash, csh, sh, tcsh, zsh - they all tell me:
command not found
Well, that's better - it tells me without insulting me that my input could not be processed. And it even hints that what I entered was treated as a command, without misleading me to file names.
An error message is the program reporting on its failure to do the job, and it is interrupting the user to do this. So it must be polite, illuminating, and helpful.
Have you never heard - The customer is always right
Long gone are the days when I last saw the (in)famous error message. Most of us would have forgotten it by now. One of the blogs that I was reading today mentioned about it. And in a rhetoric manner.
Why would you want to tell someone that something they entered is bad? Or something bad has happened? Isn't that really foolish? Didn't Mom tell them: "If you can't say anything nice, don't say anything at all." At least, don't say a bad word.
A major reason why software is not easy to learn is that it doesn't give positive feedback. We learn better from positive feedback, rather than from negative feedback. Would you prefer a hired ski instructor who yells at you? Or a restaurant host who loudly announces to other patrons that your credit card was rejected? Certainly not. Then why the should software tell me that I failed?
In my opinion, to be given negative feedback by software - any software - is an insult to human. Yes, I've read the three laws of robotics, and can recite them for you even during sleep.
Forget robotics and the mean machines, but for me, to be told by software that you have failed is degrading. And the same should be for everyone. There is nothing so important inside that dumb box that you can justify degrading a human user. If you want to protect you files, do it. But do so without bothering me. It's all right to protect the computer but not at the cost of bothering the user.
If I mistype a command, with bash, csh, sh, tcsh, zsh - they all tell me:
command not found
Well, that's better - it tells me without insulting me that my input could not be processed. And it even hints that what I entered was treated as a command, without misleading me to file names.
An error message is the program reporting on its failure to do the job, and it is interrupting the user to do this. So it must be polite, illuminating, and helpful.
Have you never heard - The customer is always right
Labels:
error
Monday, November 17, 2008
How to count occurences of a tag in an xml file
How can you find out total occurrences of a particular tag in an XML file? Say, I want to find out how many property tags are present in an XML file.
grep is not sufficient for this task. Here is a perl script that does the job.
#!/usr/bin/perl
# count_xml_tags.pl
my $xml_tag = shift;
my $filename = shift;
my $count = 0;
open (X_FILE, '<', $filename) or die "Failed to read file $filename : $!";
{
local $/;
while (<X_FILE>) {
while (m# <$xml_tag>(.*?)</$xml_tag> #gs) {
$count++;
}
}
}
close (X_FILE);
print "$count $xml_tag tag(s) found.\n";
Run this script as:
% perl count_xml_tags.pl some_tag filename.xml
grep is not sufficient for this task. Here is a perl script that does the job.
#!/usr/bin/perl
# count_xml_tags.pl
my $xml_tag = shift;
my $filename = shift;
my $count = 0;
open (X_FILE, '<', $filename) or die "Failed to read file $filename : $!";
{
local $/;
while (<X_FILE>) {
}
close (X_FILE);
print "$count $xml_tag tag(s) found.\n";
Run this script as:
% perl count_xml_tags.pl some_tag filename.xml
Labels:
perl
How to remove duplicate lines from a file
Our on-line publishing system has a text file that contains certain entries, one per line. Some entries were duplicate, and we wanted to remove them.
This can be done using sort and uniq commands.
sort /foo/bar | uniq > /new/bar
But we wanted to retain the order of lines, and so didn't want to sort the file. I found a solution using awk.
awk '!x[$0]++' /foo/bar > /new/bar
And how do I check if the file contains duplicate lines or not? The -d option of uniq command is helpful in this case.
sort /foo/bar | uniq -d
This can be done using sort and uniq commands.
sort /foo/bar | uniq > /new/bar
But we wanted to retain the order of lines, and so didn't want to sort the file. I found a solution using awk.
awk '!x[$0]++' /foo/bar > /new/bar
And how do I check if the file contains duplicate lines or not? The -d option of uniq command is helpful in this case.
sort /foo/bar | uniq -d
Saturday, August 2, 2008
How to convert Unix time to human readable format
Unix-like operating systems maintain time as the number of seconds elapsed since midnight UTC of January 1, 1970. For example, 1217646573 represents Sat Aug 2 08:39:33 2008.
How do you convert time mentioned in the Unix time format to human readable format? Perl is handy in this situation.
% perl -e 'print scalar localtime(1217646573), "\n";'
I used to work with a network monitoring software that produced logs containing time stamps in Unix time. Analyzing the logs would be difficult unless the time stamps were replaced by a human readable format.
The logs were as shown below.
STATUS [1217650382] Event: Description
Here's a perl one-liner that does the job.
% perl -pi -e 's#(?<=\[)(\d+)(?=])#scalar localtime($2)#e' /foo/bar
How do you convert time mentioned in the Unix time format to human readable format? Perl is handy in this situation.
% perl -e 'print scalar localtime(1217646573), "\n";'
I used to work with a network monitoring software that produced logs containing time stamps in Unix time. Analyzing the logs would be difficult unless the time stamps were replaced by a human readable format.
The logs were as shown below.
STATUS [1217650382] Event: Description
Here's a perl one-liner that does the job.
% perl -pi -e 's#(?<=\[)(\d+)(?=])#scalar localtime($2)#e' /foo/bar
Friday, August 1, 2008
My Geek Code
-----BEGIN GEEK CODE BLOCK-----
Version 1.0
GO d-@ s: a- C++$ UBL++>$ P+++>$ L+++>$
E- W++ N+ o K w-- !O- !M- V-
@PS+ @PE++ Y+ !PGP
t 5 X R+++ tv b+> DI++ D G
e++ h--- r+++ y+++
------END GEEK CODE BLOCK------
Version 1.0
GO d-@ s: a- C++$ UBL++>$ P+++>$ L+++>$
E- W++ N+ o K w-- !O- !M- V-
@PS+ @PE++ Y+ !PGP
t 5 X R+++ tv b+> DI++ D G
e++ h--- r+++ y+++
------END GEEK CODE BLOCK------
Thursday, July 31, 2008
How to find out if a given year is a leap year or not?
Well, for that, how do you define a leap year?
Leap year is every year the number of which is a multiple of four, except those devisible by 100 and not by 400.
Here are the steps to determine if a given year is a leap year or not:
if year modulo 400 is 0 then leap
else if year modulo 100 is 0 then no_leap
else if year modulo 4 is 0 then leap
else no_leap
Here is one Perl implementation.
#!/usr/bin/perl
use strict;
use warnings;
###### is_leap_year ######
# Purpose : To determine whether a given year is a leap year or not
# Arguements : One
# First (Number): Year to be checked
# Returns : Boolean value indicating whether given year is a leap year or not
# true = given year is a leap year
# false = given year is not a leap year
############################
sub is_leap_year ($)
{
my $year = shift;
return unless ($year =~ m/^\d+$/);
if (($year % 400) == 0) {
# This year is completely divisible by 400
return 1; # This is a leap year
}
elsif (($year % 100) == 0) {
# This year is completely divisible by 100
return 0; # This is not a leap year
}
elsif (($year % 4) == 0) {
# This year is completely divisible by 4
return 1; # This is a leap year
}
return 0; # This is not a leap year
}
my $this_year = 2040;
if (is_leap_year ($this_year)) {
print $this_year, " is a leap year\n";
}
else {
print $this_year, " is a not a leap year\n";
}
Leap year is every year the number of which is a multiple of four, except those devisible by 100 and not by 400.
Here are the steps to determine if a given year is a leap year or not:
if year modulo 400 is 0 then leap
else if year modulo 100 is 0 then no_leap
else if year modulo 4 is 0 then leap
else no_leap
Here is one Perl implementation.
#!/usr/bin/perl
use strict;
use warnings;
###### is_leap_year ######
# Purpose : To determine whether a given year is a leap year or not
# Arguements : One
# First (Number): Year to be checked
# Returns : Boolean value indicating whether given year is a leap year or not
# true = given year is a leap year
# false = given year is not a leap year
############################
sub is_leap_year ($)
{
my $year = shift;
return unless ($year =~ m/^\d+$/);
if (($year % 400) == 0) {
# This year is completely divisible by 400
return 1; # This is a leap year
}
elsif (($year % 100) == 0) {
# This year is completely divisible by 100
return 0; # This is not a leap year
}
elsif (($year % 4) == 0) {
# This year is completely divisible by 4
return 1; # This is a leap year
}
return 0; # This is not a leap year
}
my $this_year = 2040;
if (is_leap_year ($this_year)) {
print $this_year, " is a leap year\n";
}
else {
print $this_year, " is a not a leap year\n";
}
Labels:
perl
Wednesday, July 30, 2008
Count number of occurrences of a word
How can you count number of occurrences of a word in a file? Say, I want to count how many times ring is present in a file.
How about using the -c option of grep?
% grep -c ring /foo/bar
And what if the file contains words such as string and rings? That would break our count of ring.
Using the -w option of grep solves this problem
% grep -cw ring /foo/bar
What if the word ring is present more than once in a line? grep would produce incorrect count in this case, since it counts the number of lines in which the pattern is found. grep is not sufficient for this job. We need something that can count multiple occurrences of a word in a line.
To get the exact count:
#!/usr/bin/perl
# search_word.pl
my $search_this = shift or exit 1;
my $count = 0;
while (<>) {
while (m/\b$search_this\b/g) {
$count++;
}
}
if ($count == 0) {
print $ARGV . "does not contain " . $search_this . "\n";
}
else {
print $ARGV . "contains " . $search_this . " " . $count . (($count == 1) ? " time\n" : " times\n");
}
Run this perl script as:
% perl search_word.pl ring filename
And what if I don't want to use Perl? Well, then this should work for you:
% grep -w -o ring /foo/bar | wc -l
How about using the -c option of grep?
% grep -c ring /foo/bar
And what if the file contains words such as string and rings? That would break our count of ring.
Using the -w option of grep solves this problem
% grep -cw ring /foo/bar
What if the word ring is present more than once in a line? grep would produce incorrect count in this case, since it counts the number of lines in which the pattern is found. grep is not sufficient for this job. We need something that can count multiple occurrences of a word in a line.
To get the exact count:
#!/usr/bin/perl
# search_word.pl
my $search_this = shift or exit 1;
my $count = 0;
while (<>) {
while (m/\b$search_this\b/g) {
$count++;
}
}
if ($count == 0) {
print $ARGV . "does not contain " . $search_this . "\n";
}
else {
print $ARGV . "contains " . $search_this . " " . $count . (($count == 1) ? " time\n" : " times\n");
}
Run this perl script as:
% perl search_word.pl ring filename
And what if I don't want to use Perl? Well, then this should work for you:
% grep -w -o ring /foo/bar | wc -l
Tuesday, July 29, 2008
Why not to use awk when sed can do the job?
- Using awk instead of sed has the price of performance and size
- compared to sed and ed, awk takes a substantially longer time to load, and does its job at a considerably slower pace
- The real distinguishing point between sed and awk as a text processor is that awk is able to work with a persistent context, whereas capabilities of sed in this area are limited to non-existent. If you - for instance - would have to sum one field to a total you would do it with awk (it would be possible to do it with sed, but would be a nightmare - poorly suited tool for the job)
Monday, July 28, 2008
Changing size of a file
How do you change the size of a file in Linux? If you are not concerned about the contents of the file, use the dd command.
So if you want to change the size to 2 MB
Note that 2 MB is 2048 KB, and not 2000 KB.
dd if=/dev/zero of=/foo/bar bs=1024 count=1
This would change the size of a file to 1 KB. inode number of the file would be preserved.So if you want to change the size to 2 MB
dd if=/dev/zero of=/foo/bar bs=1024 count=2048
Note that 2 MB is 2048 KB, and not 2000 KB.
Labels:
Linux
Sunday, July 27, 2008
Epigram on a Software Laird
Bless Linus Torvalds, O Engineer,
With grateful, lifted eyes,
Who taught that not the windows alone,
But doors too shall open;
For had He said "the doors alone
From source I will deliver,"
Alas, alas! O Engineer,
Then hadst thou lain for ever.
Original work: Epigram on a Country Laird by Robert Burns
With grateful, lifted eyes,
Who taught that not the windows alone,
But doors too shall open;
For had He said "the doors alone
From source I will deliver,"
Alas, alas! O Engineer,
Then hadst thou lain for ever.
Original work: Epigram on a Country Laird by Robert Burns
Labels:
Epigram
Tuesday, July 22, 2008
Sorting alphanumeric strings in Perl
One of my friends had trouble sorting alphanumeric strings in Perl. Strings he had were similar to:
He wanted to sort them based on the numbers that follow after the alphabtic part. So, the order he wanted:
I extracted the numeric part from the alphanumeric string and used it for comparisons
child1
child3
child11
child51
child5
child24
child3
child11
child51
child5
child24
He wanted to sort them based on the numbers that follow after the alphabtic part. So, the order he wanted:
child1
child3
child5
child11
child24
child51
child3
child5
child11
child24
child51
I extracted the numeric part from the alphanumeric string and used it for comparisons
@alphanumeric_sorted = sort { substr($a, 5) <=> substr($b, 5)} @alphanumeric;
Monday, July 21, 2008
Apache Lyrics
Sometime last year I wrote parody of a famous song. Some of the lines of this song are in Spanish, and you need to know a bit of Spanish to understand them.
"Ports Won't Die"
(feat. Office Assistant)
Macros up in here tonight
No fighting, no fighting
We got the fixes up in here
No fighting, no fighting
Apache, Apache
I never really knew that it could serve so fast
It makes a man wants to HTTP
Como se llama (si), bonita (si), mi OS (si, Apache Apache), su OS
Apache, Apache
Oh baby when you talk like that
You make IIS go mad
So be wise and keep on
Reading the signs of my Ballmer
And I'm on tonight
You know my ports won't die
And I'm starting to feel it's right
All the attraction, the tension
Don't you see baby, this is perfection
Hey Girl, I can see your traffic moving
And it's driving me crazy
And I didn't have the slightest idea
Until I saw you serving
And when you take up a bad request
Nobody cannot ignore the way you check it out, girl
And architecture so perfected - the way you right and left it
So you can keep on excelling
I never really knew that it could serve so fast
It makes a man want to HTTP
Como se llama (si), bonita (si), mi OS (si, Apache Apache), su OS
Apache, Apache
Oh baby when you talk like that
You make IIS go mad
So be wise and keep on
Reading the signs of my Ballmer
And I'm on tonight
You know my ports won't die
And I am starting to feel you boy
Come on lets go, real slow
Don't you see baby asi es perfecto
Oh I know I am on tonight my ports won't die
And I am starting to feel it's right
All the attraction, the tension
Don't you see baby, this is perfection
Apache, Apache
Oh boy, I can see your traffic moving
Half filtered, half cached
I don't, don't really know what I'm doing
But you seem to have a plan
My will and self restraint
Have come to fail now, fail now
See, I am doing what I can, but I can't so you know
That's a bit too hard to explain
Roca en el Internet toda la noche
Roca en el Internet toda el día
Roca en el Internet toda la noche
Roca en el Internet toda el día
I never really knew that it could serve so fast
It makes a man want to HTTP
Como se llama (si), bonita (si), mi OS (si, Apache Apache), su OS
Apache, Apache
Oh baby when you talk like that
You know you got me hypnotized
So be wise and keep on
Reading the signs of my Ballmer
Senorita, feel the conga, let me see you serve like you come from Redmond
Mira en Maryland se baila así, say it!
Mira en Maryland se baila así
Yeah
It's so popular, macro shaft's jealousy a refugee like me back with the Fugees from a buggy territory
I go back like when 'pac carried crates for Humpty Humpty
I need a whole club dizzy
Why the Court wanna break us?
Explorers and Windows
I ain't guilty, it's no monopoly transaction
No more do we snatch ropes
Refugees run the seas 'cause we own our own browser
I'm on tonight, my ports won't die
And I'm starting to feel you boy
Come on let's go, real slow
Baby, like this is perfecto
Oh, you know I am on tonight and my ports won't die
And I am starting to feel it's right
The attraction, the tension
Baby, like this is perfection
No fighting
No fighting
(feat. Office Assistant)
Macros up in here tonight
No fighting, no fighting
We got the fixes up in here
No fighting, no fighting
Apache, Apache
I never really knew that it could serve so fast
It makes a man wants to HTTP
Como se llama (si), bonita (si), mi OS (si, Apache Apache), su OS
Apache, Apache
Oh baby when you talk like that
You make IIS go mad
So be wise and keep on
Reading the signs of my Ballmer
And I'm on tonight
You know my ports won't die
And I'm starting to feel it's right
All the attraction, the tension
Don't you see baby, this is perfection
Hey Girl, I can see your traffic moving
And it's driving me crazy
And I didn't have the slightest idea
Until I saw you serving
And when you take up a bad request
Nobody cannot ignore the way you check it out, girl
And architecture so perfected - the way you right and left it
So you can keep on excelling
I never really knew that it could serve so fast
It makes a man want to HTTP
Como se llama (si), bonita (si), mi OS (si, Apache Apache), su OS
Apache, Apache
Oh baby when you talk like that
You make IIS go mad
So be wise and keep on
Reading the signs of my Ballmer
And I'm on tonight
You know my ports won't die
And I am starting to feel you boy
Come on lets go, real slow
Don't you see baby asi es perfecto
Oh I know I am on tonight my ports won't die
And I am starting to feel it's right
All the attraction, the tension
Don't you see baby, this is perfection
Apache, Apache
Oh boy, I can see your traffic moving
Half filtered, half cached
I don't, don't really know what I'm doing
But you seem to have a plan
My will and self restraint
Have come to fail now, fail now
See, I am doing what I can, but I can't so you know
That's a bit too hard to explain
Roca en el Internet toda la noche
Roca en el Internet toda el día
Roca en el Internet toda la noche
Roca en el Internet toda el día
I never really knew that it could serve so fast
It makes a man want to HTTP
Como se llama (si), bonita (si), mi OS (si, Apache Apache), su OS
Apache, Apache
Oh baby when you talk like that
You know you got me hypnotized
So be wise and keep on
Reading the signs of my Ballmer
Senorita, feel the conga, let me see you serve like you come from Redmond
Mira en Maryland se baila así, say it!
Mira en Maryland se baila así
Yeah
It's so popular, macro shaft's jealousy a refugee like me back with the Fugees from a buggy territory
I go back like when 'pac carried crates for Humpty Humpty
I need a whole club dizzy
Why the Court wanna break us?
Explorers and Windows
I ain't guilty, it's no monopoly transaction
No more do we snatch ropes
Refugees run the seas 'cause we own our own browser
I'm on tonight, my ports won't die
And I'm starting to feel you boy
Come on let's go, real slow
Baby, like this is perfecto
Oh, you know I am on tonight and my ports won't die
And I am starting to feel it's right
The attraction, the tension
Baby, like this is perfection
No fighting
No fighting
Labels:
Apache
Subscribe to:
Posts (Atom)