Sunday, September 7, 2008

Automatic Command Archive

The default command storing size of ubuntu is 500 commands. It stores the commands in home folder in the file ".bash_history" .
The problem is 500 commands is too short of a size.
One method is to increase the command size to a large value by changing the $HISTFILESIZE variable using the following command
export HISTFILESIZE=1000

But this will last only till that terminal is closed.

Do make tat permanent or rather make that command execute every time u open a terminal we can put that command in .bashrc file in the home folder itself
The commands in this folder will be executed each time you open a terminal. So adding that command is one way to solve tat problem.

Or there is another way. Make a script tat will automatically archive the old commands to a file and compress it and save if it bigger than a specified size. That's a better method i feel.
Also i try to remove the repeated commands and store only unique ones there by not wasting space storing copies. This is a better method i feel than making it accumulate in the .bashrc.
So let's see how to do it.
File name:logarchive

echo "Ran at:"$(date) >>/home/$1/logs/commandrotate
echo "Size of History: "$(cat /home/$1/.bash_history|wc -l) >>/home/rsrijith/logs/commandrotate
if [ $(cat /home/$1/.bash_history|wc -l) -gt 400 ]
then
echo "Archived" >>/home/rsrijith/logs/commandrotate
cat -n /home/$1/.bash_history|sort -ru -k2|sort -n -k1|sed 's/[ ]*[0-9]*\t//' > /home/$1/.bash_history
cat /home/$1/.bash_history >>/home/$1/history/cmd_history
touch /home/$1/history/temp
cat -n /home/$1/history/cmd_history|sort -ru -k2|sort -n -k1|sed 's/[ ]*[0-9]*\t//' >/home/$1/history/cmd_history
tail -100 /home/$1/.bash_history >/home/$1/history/temp
cat /home/$1/history/temp >/home/$1/.bash_history
rm /home/$1/history/temp
fi
logrotate /home/$1/history/logrot.conf
if [ -e /home/$1/history/cmd_history.1 ]
then
gunzip "/home/$1/history/cmd_archive.gz"
cat /home/$1/history/cmd_history.1 >>/home/$1/history/cmd_archive
gzip -f "/home/$1/history/cmd_archive"
rm /home/$1/history/cmd_history.1
rm /home/$1/history/cmd_archive
fi

This script also reduces the current .bashrc file to only unique entry.Although there is a command (or rather environment variable) to store only unique values. But that only keeps the first entry in the file.So only the initial entry stays. I usually use the recently used commands using the up arrow in bash. So I need to maintain the order in which I have typed the command too. That's why I have used cat -n to get the order and have used it to order it in the end.
I have made the script run when the commands exceeds 400.

Once the cmd_history file goes over 1MB ,I try to compress it and store in as an archive. This is why i have used logrotate file

File name:logrot.conf

/home/rsrijith/history/cmd_history {
missingok
size 1M
rotate 1
}

Now we need to run it every 30mins or 1hr according to how much you use the commands.I have used 30mins just in case.So we use crontab (A scheduler in Linux).The crontab file is /etc/crontab.We can edit it using the command.
crontab -e

As we need to run it as root.Run the command as root.
So the crontab entry is as

*/30 * * * * root /home/rsrijith/history/logarchive rsrijith 2>>/home/rsrijith/logs/commandrotate

1 comment:

  1. Hey!
    KISS -> Keep it simple and Stupid. :D


    #!/bin/bash
    #Filename : storehist.sh
    #Description: History storage script

    size=`cat ~/.bash_history | wc -l`;

    function dup_remove()
    {
    cat -n $1 | sort -urk2 | sort -n | cut -f2;
    }


    mkdir -p ~/.logs/archive;

    if [ $size -gt 400 ];
    then
    echo "History log sent to ~/.logs/history :$(date)";

    dup_remove ~/.bash_history >/tmp/history.$$;
    cat /tmp/history.$$ >> ~/.logs/history;
    cat /tmp/history.$$ | tail -n 400 > ~/.bash_history;
    fi;

    if [[ `du -sh ~/.logs/history` =~ "M" ]];
    then

    echo "Archived on `date`";
    dup_remove ~/.logs/history > /tmp/history.$$;
    cat /tmp/history.$$ > ~/.logs/history;
    gzip -c ~/.logs/history > ~/.logs/archive/$(date);
    > ~/.logs/history;
    fi;


    #crontab entry as:
    * */1 * * * storehist.sh

    ReplyDelete