This page features my Unix/Linux shell, Perl, PHP and Javascript scripts that I have made over the years that may be beneficial to other people. There are also some useful configuration directives included for popular unix software packages.
Unix/Linux shell (/bin/sh) scripts:
Featured PHP scripts:
Configurations:
Patches:
If you wish to contact me regarding anything here, please do so using this email address: erikjantaal@xs4all.nl
Have a look around my main website.
The Debian linux distribution features a famous utility called apt-get. I wanted to have a similar program for FreeBSD but none existed, or at least I didn't find them.
My requirements were as follows: To install packages from the FreeBSD ftp server while saving them in a cache for use on other machines. This script turns out to be very usefull if your boss tells you that 9 servers will be delivered today which have to be installed and configured before being placed at the co-lo site tomorrow. I did manage to average around 15 minutes per server that day leaving the total time spent a little over 2 hours ;)
When you run the script for the first time it will download the ports INDEX file from the server. This is used for determining which package you want to search for or want to have installed.
When you download the script you have to tune some variables:
- set $CACHEDIR to something where you have a lot of space because that is the directory
in which the downloaded packages will be saved prior to installation.
- set $BASEURL to a fast mirror url for your location. Simply check the value
that is currently there and adjust it to point to your fastest local mirror site
TODO:
I'd like to merge these 2 scripts into a generic apt-get-bsd.sh script, however I am lacking
the time to do so and on top of that the name would imply that the other BSDs are supported
as well, which they are not ;)
Any comments, suggestions or fixes are welcome of course.
Now on to the downloads:
apt-get-freebsd.sh for use on FreeBSD
apt-get-freebsd.sh for use on OpenBSD
To work more effeciently with my repository files I frequently use the following 3 scripts. If you also work a lot with repositories in either of the CVS, Subversion or SVK formats, and you are a vi/vim user then these scripts may be useful to you!
After having done some work in your working copy you would normally call the relevant commit commands and type a commit message. However, upon doing this there is only limited information as to which changes you have made because only a list of files that have been modified is given.
So instead of calling the usual 'cvs commit', 'svn commit' or 'svk commit' I call my script 'nice-commit.sh' with any optional arguments as I normally would with the normal commit call.
First the script auto detects which repository is being used, after which it generates a 'diff -u' patch file of the changes in the specified files, or the current directory if no files were specified.
After this it calls the relevant commit command and brings up the vim editor with 2 windows, where the top windows displays the generated patch file, and the familiar log message input file at the bottom. Now you can scroll through your changes in the top window and document them one by one in a meaningfull and comprehensive way in the bottom window.
Here is an example of what you might see when you call nice-commit.sh (here shown
while using subversion)
screenshot:
nice-commit.sh
Tip: when you have typed your log message, type ':xall' (you can type :xa[tab]) to exit from both windows at once, since ':wq' would only close your active window, requiring you to close the second window as well. Alternatively you can type ':wqall'.
To view the changes that I have made in my working copy, I call the script repdiff.sh which autodetects the repository type being used, and generates a diff -u of the specified files or the working directory if no files were specified, and opens the patch with the vim editor. A shortcut is set so that simply pressing the letter 'q' will exit from vim, similarly to the programs 'less' and 'man'.
Even more useful is to show the changes that were made to a file during its last commit action. For this information, I made a script called last-commit-diff.sh. It autodetects the type of repository used, after which it will perform a 'log' query to find out the previous commit version of that file, and subsequently generates a diff of the current (repository) version and the previous version.
On to the downloads:
nice-commit.sh
repdiff.sh
last-commit-diff.sh
I have setup my bash prompt to display the following items:
Here is an example session of my prompt:
screenshot:
bash example session
It is accomplished with the following piece of code in my ~/.bash_profile:
# Ph34r |\/|y l33t 845h Pr0|\/|p7 ;)
uname=$(uname)
tty=$(tty | sed -e 's#^/dev/##')
export PROMPT_COMMAND="
# Get exit code to use later
LASTEXIT=\$?;
USERNAME=\$(whoami)
# 27 is length of prompt minus all variable space
PROMPTLENGTH=\$((27+\$(echo -n \"\${USERNAME}${HOSTNAME}${uname}${tty}\" | wc -c)))
COLUMNSLEFT=\$((\$COLUMNS-\$PROMPTLENGTH))
MYPWD=\$(pwd | sed 's#^$HOME#~#')
PWDLENGTH=\$(echo -n \"\$MYPWD\" | wc -c)
if [ \"\$PWDLENGTH\" -lt \"\$COLUMNSLEFT\" ]; then
PROMPTDIR=\"\$MYPWD\"
else
# There's not enough space to print the pwd, so print equal parts of the left and right side
PROMPTDIR=\"\$(echo \"\$MYPWD\" | cut -b -\$((COLUMNSLEFT/2-2)))...\$(echo \"\$MYPWD\" | cut -b \$((PWDLENGTH-(COLUMNSLEFT/2)+2))-)\"
fi
# Set a nicer window title for screen
SCREENTITLE=\$(pwd | sed 's#^$HOME#~#' | sed 's/^\(............\).*/\1/');
echo '$TERMCAP' | grep -q 'screen' && echo -n -e \"\033k\$SCREENTITLE\033\134\";
# If we are in konsole or ssh
if [ -n '$SSH_CLIENT' -o -n '$KONSOLE_DCOP' ]; then
# Set konsole window title
echo -n -e \"\e]0;\$(whoami) @ $HOSTNAME | \$PROMPTDIR | \a\";
fi
# Start bold text
echo -n -e '\e[1m';
# True if we are root
if [ \$(id -u) = '0' ]; then
# Start red colour
echo -n -e '\e[31m';
else
# Start green colour
echo -n -e '\e[32m';
fi;
# Echo username,tty,hostname,uname,time
echo -n -e \"\$USERNAME\e[0m[$tty]@\e[1m\e[33m$HOSTNAME\e[0m($uname) | \e[1;34m\"
echo -n \$(date +'%H:%M:%S')
echo -n -e '\e[0m | \e[1m';
# If last command was successful
if [ \$LASTEXIT -eq 0 ]; then
# Echo green happy smiley
echo -n -e '\e[32m:)\e[0m';
else
# Echo red sad smiley
echo -n -e '\e[31m:(\e[0m';
fi;
# Echo numeric exit code + pwd, leave out -n as we want a new line now
echo -e \" \$LASTEXIT | \$PROMPTDIR\";
";
export PS1="> "
export PS2=' '
Furthermore, commands which can take a while or that connect to remote hosts are set to display the
commandline in the XTerm/konsole title bar and/or the screen window title in the following way:
screenshot:
xterm titlebar
This is accomplished with the following piece of code in my ~/.bash_profile:
konsole_title() {
# Prepare nice directory
CURDIR=$(pwd | sed -e 's#\(/[^\/]*/[^\/]*\)/.*/\([^\/]*/[^\/]*\)\$#\1...\2#g');
# If we are in konsole or ssh
if [ -n "$SSH_CLIENT" -o -n "$KONSOLE_DCOP" ]; then
# Set konsole window title
echo -ne "\e]0; ::: $@ ::: | ${USER} @ ${HOSTNAME} | $CURDIR | \a";
fi
SCREENTITLE=$(echo "$@" | sed -e "s# $HOME# ~#" | sed -e 's/^\(............\).*/\1/');
echo "$TERMCAP" | grep -q 'screen' && echo -e "\ek${SCREENTITLE}\e\\"
"$@"
}
# konsole_title aliases
alias irssi='konsole_title irssi'
alias links='konsole_title links'
alias make='konsole_title make'
alias man='konsole_title man'
alias mplayer='konsole_title mplayer'
alias mutt='konsole_title mutt'
alias ping='konsole_title ping'
alias screen='konsole_title screen'
alias snownews='konsole_title snownews'
alias ssh='konsole_title ssh'
alias sudo='konsole_title sudo'
alias tail='konsole_title tail'
alias telnet='konsole_title telnet'
alias vim='konsole_title vim'
alias wget='konsole_title wget'
The program scp, after many years of development, still doesn't have a resume option. In the case where you have access to a server, but for some reason or another cannot use rsync, the following script would be very useful for resuming uploads or downloads via ssh. The script assumes that the utility 'dd' is available both on the local and on the remote host.
The initial script was made to resume some transfers over a slow internet connections. I didn't realize that the script had a bottleneck due to using a 1 byte blocksize being used for dd, which was to simplify the calculations and to be able to use 'cat >>' at the other end instead of a 'dd seek' command. To improve the speed nitro (dot) tm (at) gmail (dot) com sent me some patches for using blocks in dd and to enable passing extra ssh arguments, such as -C for compression. These patches have been slightly improved and included in the latest version.
On to the download: scp-resume.sh
Did you ever wanted to keep a record of all the tweaks that you made to files in /etc and your ~/.* ($HOME directory dotfiles)? I did and I didn't want to keep an entire copy of /etc and my $HOME directory completely under version control like this guy ,but just the files that I feel are important to keep.
To enable this I developed a script called manage-conf-files.sh to keep track of changes to my configuration files. This script requires two other programs for its functionality: subversion for version control of the files and rsync for easily copying a set of files.
To start using this script you need to do the following after installing the above mentioned utilities: 1. Create and checkout a repository for use with this script. This can be as easy as doing the following in your home directory:
$ mkdir svn && svnadmin create svn/configfiles $ mkdir work && cd work && svn co file://$HOME/svn/configfiles
If you've already setup a repository for your files and simply want to include the configuration files in a directory under it, simply edit the first line of the script and point it to the directory under which you want the version controlled files to be stored.
Simply run the script without any arguments to learn how to use it. I hope you will find this script usefull.
On to the download: manage-conf-files.sh
Looking for an easy but secure way to encrypt/decrypt files? I have setup some scripts to automate encrypting files using my favorite opensource program openssl utilising blowfish encryption with a public key used for the passphrase that the blowfish encryption will use. The procedure is outlined below:
How to make secure backups: 1. Generate a RSA private key: openssl genrsa -out backup-key 2048 2. encrypt the private key with a keyphrase: openssl rsa -in backup-key -aes128 -out backup-key.enc ( or the previous 2 steps in one command: openssl genrsa 2048 | openssl rsa -aes128 -out backup-key.enc) 3. Generate the corresponding public key: openssl rsa -in backup-key.enc -pubout -out backup-key.pub You should now ideally properly delete the unencrypted private key by overwriting a couple of times before deleting it. After creating a backup file: 1. Get 32 bytes of random data dd if=/dev/urandom of=backup.tar.gz.key bs=1 count=32 2. Encrypt your backup with Blowfish encrpytion, using the random data as the passphrase: openssl enc -bf -in backup.tar.gz -out backup.tar.gz.enc -pass file:./backup.tar.gz.key 3. Encrypt the random key using the public key of your main backup key: openssl rsautl -encrypt -pubin -inkey backup-key.pub -in backup.tar.gz.key -out backup.tar.gz.key.enc 4. Now you may securely delete the random data file: rm -P backup.tar.gz.key Decrypting the backup: 1. Decrypt the random data using your private backup key: openssl rsautl -decrypt -inkey backup-key.enc -in backup.tar.gz.key.enc -out backup.tar.gz.key 2. Decrypt the backup file using the random data as passphrase for the Blowfish decryption: openssl enc -d -bf -in backup.tar.gz.enc -out backup.tar.gz -pass file:./backup.tar.gz.key
You'll have to generate the backup key manually yourself. I've placed my backup key in /home/backup.key. If you place your key somewhere else you need to adjust the scripts for this.
On to the downloads:
encrypt-file.sh
decrypt-file.sh
If you're using KDE, you might know that it allows you to specify a program to generate the desktop background. I have written a script that is compatible with KDE and does the following:
Here is an example of what a wallpaper would look like when run with the following commandline:
kde-wallpaper.sh 450 360 ~/kde-wallpaper-sample.jpg /data/wallpapers/
To configure this script for use with your KDE deskop, configure your desktop,
select 'No Picture', then click on 'Advanced options', tick 'use the following program...' and
click add. Then fill out the details as seen on the following screenshot. Make sure you specify the
full path to the kde-wallpaper.sh script in the box.
screenshot:
How to configure the wallpaper changer
Note that in order to function this script requires ImageMagick installed on your machine.
On to the download: kde-wallpaper.sh
If you're developing PHP webinterface scripts you might know about the Smarty template engine. It provides a way of setting up fairly complex HTML templates for use in your script. I've written the mini-template class as a minimal replacement of the much larger Smarty class. A sample template, code snippet and resulting output are shown below:
<html><head><title>{$title}</title></head>
<body> [[ <h1>{$pagebanner}</h1> ]] </body></html>
# Sample php script using mini-template include_once( "minitemplate.class.php" ); $minitemplate = new minitemplate; $minitemplate->templatedir = '/var/www/template'; #where to look for templates $output['title'] = 'Welcome to my website!'; $output_page = $minitemplate->fillout( "sample.tpl", $output); print $output_page;
<html><head><title>Welcome to my website!</title></head> <body> </body></html>
Currently, the only things the mini-template does are:
On to the download: minitemplate.class.php
I have configured GNU screen to display a userfriendly title bar and window list in the bottom
2 rows of the screen. Behold this screenshot:
screenshot:
GNU screen windowlist and titlebar
It is accomplished with the following configuration in my ~/.screenrc
hardstatus alwayslastline
caption always "%{= C}screen[%n] | %c | %h%="
hardstatus string "%{= .W}%-Lw%{= C}%50>[%n* %t]%{-}%+Lw%<"
windowlist string " screen[%n %t] %h"
Here is the .vimrc that I've used for quite some time now:
set ruler
set bs=2
set ai
set ts=2
set nowrap
syntax on
set nohlsearch
set expandtab
au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal g'\"" | endif
set viminfo='20,\"50
set history=50
set background=dark
It takes care of the following things:
Since I'm used to using the -v flag for the cp/mv/rm utilities under linux and I like to keep my .bash_profile generic across all the machines I have access to, I've found a way to enable similar beheaviour in OpenBSD. It doesn't natively support the -v flag, even though people have asked for it in the past.
This patch was written on a clean OpenBSD 3.8 install. It has also been updated with a patch for the manual pages for the affected binaries, so that the -v flag is briefly described. The previous version of this patch, which is for OpenBSD 3.7 is also offered for download below.
To apply this patch, make sure that you have installed the OpenBSD source tree as usual in /usr/src and execute the followings steps as user root:
1. cd /usr/src 2. patch < /path/to/downloaded/openbsd-vpatch.diff 3. for i in cp mv rm; do cd /usr/src/bin/$i; make clean && make && make install; done
On to the download:
vflag-patch.diff (for OpenBSD 3.8 RELEASE)
openbsd-3.7-vflag-patch.diff (for OpenBSD 3.7 RELEASE)