Thursday, October 29, 2009

When Did I Install This?

I use chrome via chromium, and I compile it every now and then, whenever I feel like it's been a while since I last compile it.

How do I know it's been a while? How long is a while?


ls -lL `which chrome`


shows me the last modification time.

But this needs some mental exercise on comparing the last modification time with the current time.

Here's my solution ...

Say hello to age:

SYNOPSIS
  age [-fh] file ...


DESCRIPTION
age shows the age of the given programs. For each argument age
locates the program executable using which(1), and then
calculates the age in days, hours, minutes and seconds. Fields
where the values are zero are not shown.

For executables age dereferences symbolic links by default.
This makes it simple to find out how old a program has been
installed on the system.

To show the age of symbolic links use the -f option instead
and specify the fullpath to the symbolic link.


Example usage:

$ age chrome
/home/nazri/bin/chrome: 1 day 21 hours 1 minute 20 seconds

$ age git
/usr/local/bin/git: 1 day 23 hours 43 seconds

$ age ls
/bin/ls: 1 year 125 days 3 hours 23 minutes 15 seconds


Neat!

Here's the full shell script:

#!/bin/sh
# age - Show age of files

me=`basename $0`
SECONDS_PER_MINUTE=60
SECONDS_PER_HOUR=3600
SECONDS_PER_DAY=86400
SECONDS_PER_YEAR=31536000

usage() {
cat << EOF
SYNOPSIS
age [-fh] file ...

DESCRIPTION
age shows the age of the given programs. For each argument age locates the
program executable using which(1), and then calculates the age in days,
hours, minutes and seconds. Fields where the values are zero are not shown.

For executables age dereferences symbolic links by default. This makes it
simple to find out how old a program has been installed on the system.

To show the age of symbolic links use the -f option instead and specify the
fullpath to the symbolic link.

OPTIONS
-h Show this help message

-f Do not locate the executable. Assume that the files are relative path
to the current directory

AUTHOR
Written by Nazri Ramliy

LICENSE
Public domain.
EOF
}

get_age() {
since=$1
now=`date +%s`
delta=$(( $now - $since ))

years=$(( $delta / $SECONDS_PER_YEAR ))
delta=$(( $delta % $SECONDS_PER_YEAR ))

days=$(( $delta / $SECONDS_PER_DAY ))
delta=$(( $delta % $SECONDS_PER_DAY ))

hours=$(($delta / $SECONDS_PER_HOUR ))
delta=$(( $delta % $SECONDS_PER_HOUR ))

minutes=$(($delta / $SECONDS_PER_MINUTE))
delta=$(( $delta % $SECONDS_PER_MINUTE ))

seconds=$delta

[ $years -gt 0 ] && out="$years year" &&
[ $years -gt 1 ] && out="${out}s"

[ $days -gt 0 ] && out="$out $days day" &&
[ $days -gt 1 ] && out="${out}s"

[ $hours -gt 0 ] && out="$out $hours hour" &&
[ $hours -gt 1 ] && out="${out}s"

[ $minutes -gt 0 ] && out="$out $minutes minute" &&
[ $minutes -gt 1 ] && out="${out}s"

[ $seconds -gt 0 ] && out="$out $seconds second" &&
[ $seconds -gt 1 ] && out="${out}s"

out=`echo $out|sed -e 's/^ *//'`
echo $out
}

find_bin=1
while getopts hf opt
do
case "$opt" in
f)
find_bin=0
;;
h)
usage
exit;;
\?) exit;;
esac
done
shift $(($OPTIND -1))

[ -z "$1" ] && usage && exit

for file in $*; do
if [ $find_bin -eq 1 ]; then
exe=`which 2>/dev/null $file`
[ $? -ne 0 ] && echo "$me: $file: No such executable" && exit 1
file=$exe
since=`stat -L --format '%Y' $file`
else
[ ! -e $file ] && echo "$me: $file: No such file" && exit 1
since=`stat --format '%Y' $file`
fi

printf "$file: "
get_age $since
done