Monday, November 17, 2008

How to calculate days between two dates in bash shell

#!/bin/bash
# days-between.sh: Number of days between two dates.
# Usage: ./days-between.sh [M]M/[D]D/YYYY [M]M/[D]D/YYYY
#
# Note: Script modified to account for changes in Bash, v. 2.05b +,
#+ that closed the loophole permitting large negative
#+ integer return values.

ARGS=2 # Two command line parameters expected.
E_PARAM_ERR=65 # Param error.

REFYR=1600 # Reference year.
CENTURY=100
DIY=365
ADJ_DIY=367 # Adjusted for leap year + fraction.
MIY=12
DIM=31
LEAPCYCLE=4

MAXRETVAL=255 # Largest permissible
#+ positive return value from a function.

diff= # Declare global variable for date difference.
value= # Declare global variable for absolute value.
day= # Declare globals for day, month, year.
month=
year=


Param_Error () # Command line parameters wrong.
{
echo "Usage: `basename $0` [M]M/[D]D/YYYY [M]M/[D]D/YYYY"
echo " (date must be after 1/3/1600)"
exit $E_PARAM_ERR
}


Parse_Date () # Parse date from command line params.
{
month=${1%%/**}
dm=${1%/**} # Day and month.
day=${dm#*/}
let "year = `basename $1`" # Not a filename, but works just the same.
}


check_date () # Checks for invalid date(s) passed.
{
[ "$day" -gt "$DIM" ] || [ "$month" -gt "$MIY" ] ||
[ "$year" -lt "$REFYR" ] && Param_Error
# Exit script on bad value(s).
# Uses or-list / and-list.
#
# Exercise: Implement more rigorous date checking.
}


strip_leading_zero () # Better to strip possible leading zero(s)
{ #+ from day and/or month
return ${1#0} #+ since otherwise Bash will interpret them
} #+ as octal values (POSIX.2, sect 2.9.2.1).


day_index () # Gauss' Formula:
{ # Days from March 1, 1600 to date passed as param.
# ^^^^^^^^^^^^^
day=$1
month=$2
year=$3

let "month = $month - 2"
if [ "$month" -le 0 ]
then
let "month += 12"
let "year -= 1"
fi

let "year -= $REFYR"
let "indexyr = $year / $CENTURY"


let "Days = $DIY*$year + $year/$LEAPCYCLE - $indexyr \
+ $indexyr/$LEAPCYCLE + $ADJ_DIY*$month/$MIY + $day - $DIM"
# For an in-depth explanation of this algorithm, see
#+ http://weblogs.asp.net/pgreborio/archive/2005/01/06/347968.aspx


echo $Days

}


calculate_difference () # Difference between two day indices.
{
let "diff = $1 - $2" # Global variable.
}


abs () # Absolute value
{ # Uses global "value" variable.
if [ "$1" -lt 0 ] # If negative
then #+ then
let "value = 0 - $1" #+ change sign,
else #+ else
let "value = $1" #+ leave it alone.
fi
}



if [ $# -ne "$ARGS" ] # Require two command line params.
then
Param_Error
fi

Parse_Date $1
check_date $day $month $year # See if valid date.

strip_leading_zero $day # Remove any leading zeroes
day=$? #+ on day and/or month.
strip_leading_zero $month
month=$?

let "date1 = `day_index $day $month $year`"


Parse_Date $2
check_date $day $month $year

strip_leading_zero $day
day=$?
strip_leading_zero $month
month=$?

date2=$(day_index $day $month $year) # Command substitution.


calculate_difference $date1 $date2

abs $diff # Make sure it's positive.
diff=$value

echo $diff

exit 0

# Compare this script with
#+ the implementation of Gauss' Formula in a C program at:
#+ http://buschencrew.hypermart.net/software/datedif

Friday, November 14, 2008

How to open SSH key from one server to another using an Example

To configure ssh from SOURCE to DESTINATION
1. On SOURCE and DESTINATION execute the following command
mkdir ~/.ssh;chmod 700 ~/.ssh.
If the directory already exists then ignore the error message

2. On SOURCE execute the following command to create private and public key
ssh-keygen -t rsa -b 2048

3. Execute the following commands on SOURCE
eval `ssh-agent`;ssh-add ~/.ssh/id_rsa;ssh-add -l

4. On SOURCE add the following code to file ~/.bashrc
SSH_ENV=$HOME/.ssh/environment
function start_agent {
echo "Initialising new SSH agent..."
/usr/bin/ssh-agent | sed 's/^echo/#echo/' > ${SSH_ENV}
echo succeeded
chmod 600 ${SSH_ENV}
. ${SSH_ENV} > /dev/null
/usr/bin/ssh-add;
}

# Source SSH settings, if applicable
if [ -f "${SSH_ENV}" ]; then
. ${SSH_ENV} > /dev/null
ps ax | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi



5. On SOURCE and execute
scp ~/.ssh/id_rsa.pub DESTINATION:~/.ssh/authorized_keys2

Enter password at the prompt
scp ~/.ssh/id_rsa.pub DESTINATION:~/.ssh/authorized_keys2

Enter password at the prompt
Go to DESTINATION and check if file authorized_keys2 is present

6. Go to SOURCE and execute
eval `ssh-agent`;ssh-add ~/.ssh/id_rsa;ssh-add -l
source ~/.bashrc

Thursday, November 13, 2008

How to create and configure SSH keys

Creating SSH keys
On a linux host begin by creating your keys using the ssh-keygen command
$ ssh-keygen -t rsa -b 2048
This will prompt you for a secret passphrase. Make sure to use a good passphrase.

Two files will be created when this completes: id_dsa and id_dsa.pub in your /home/$USER/.ssh dir.

Note: it is possible to just press the enter key when prompted for a passphrase, which will make a key with no passphrase. This is a Bad Idea for an identity key, so don't do it!

The id_dsa is your private key which needs to reside on the server where you wish to originate your ssh connection (~/.ssh/id_rsa). The id_dsa.pub is your public key, and needs to be copied into the ~/.ssh/authorized_keys file on the destination server. To copy the key to your destination server:

$ scp ~/.ssh/id_rsa.pub DESTINATION_HOST:.ssh/authorized_keys2

Using ssh-agent
So, your key has been created and you've copied the public key to all your destination hosts. Here's how you can avoid entering the key's passphrase each time.

Startup ssh-agent using eval which will run it in your current shell
eval `ssh-agent`

Now, we'll add the keys into the agent.
ssh-add ~/.ssh/id_rsa

You can now list the key(s) in your agent:
ssh-add -l
2048 cc:ae:81:d4:d8:dc:1e:12:38:87:cf:1d:83:91:26:df id_rsa (RSA)


Using this shell, you can now ssh to your destination hosts without re-entering the key's passphrase.

To automate ssh-agent, you can place the following into your .bashrc file:
SSH_ENV=$HOME/.ssh/environment

function start_agent {
echo "Initialising new SSH agent..."
/usr/bin/ssh-agent | sed 's/^echo/#echo/' > ${SSH_ENV}
echo succeeded
chmod 600 ${SSH_ENV}
. ${SSH_ENV} > /dev/null
/usr/bin/ssh-add;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
. ${SSH_ENV} > /dev/null
ps ax | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;