Tag Archives: ssh

Mix in some CLI fun on your server

This post is directed at Ubuntu and Debian server admins. As all work and no play makes Jack a dull boy, it is imperative that you immediately make your server more fun. If you do not get a little smile when you log into your server via SSH, then something is terribly wrong! Avoid dullness by all means.

Here I will show how to add and use figlet, fortune, cowsay and xmlstarlet to have big banners, random quotes’n’quips, talking cows and word of the day appear when using SSH to access your server.

FIGlet is a program for making large letters out of ordinary text.

FIGlet project: http://www.figlet.org/

Fortune is a simple program that displays a random message from a database of quotations.

Cowsay is a filter that takes text and displays a cow saying it.

Cowsay project page: http://www.nog.net/~tony/warez/cowsay.shtml

Cowsay article: http://linuxgazette.net/issue67/orr.html

XMLStarlet is a set of command line utilities (tools) which can be used to transform, query, validate, and edit XML documents and files using simple set of shell commands in similar way it is done for plain text files using UNIX grep, sed, awk, diff, patch, join, etc commands.

XMLSartlet project page: http://xmlstar.sourceforge.net/overview.php

Adding Universe and Multiverse Repository in Ubuntu

These packages are in the Universe and Multiverse repositories. If you need to add these repositories, just un-remark the pertinent lines in /etc/apt/sources.list and run aptitude update:

First, make a backup of the original /etc/apt/sources.list file.

sudo cp /etc/apt/sources.list /etc/apt/sources.list.original

Edit /etc/apt/sources.list:

sudo vi /etc/apt/sources.list

Un-remark the universe and multiverse lines (remove the leading # character) so the lines look something like this:

deb http://us.archive.ubuntu.com/ubuntu/ lucid universe
deb-src http://us.archive.ubuntu.com/ubuntu/ lucid universe
deb http://us.archive.ubuntu.com/ubuntu/ lucid-updates universe
deb-src http://us.archive.ubuntu.com/ubuntu/ lucid-updates universe
deb http://us.archive.ubuntu.com/ubuntu/ lucid multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ lucid multiverse
deb http://us.archive.ubuntu.com/ubuntu/ lucid-updates multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ lucid-updates multiverse

Finish by retrieving the updated package lists to your system with:

sudo aptitude update

By the way, to search for packages in the Ubuntu packages repositories, visit:



Figlet creates character graphic block letter banners. Thus:



                       ___      ___ 
   ____ ___  ___  ____/ (_)___ |__ \
  / __ `__ \/ _ \/ __  / / __ `/_/ /
 / / / / / /  __/ /_/ / / /_/ / __/ 
/_/ /_/ /_/\___/\__,_/_/\__,_/____/ 

Install Figlet

On an Unbuntu/Debian system, install figlet like this:

sudo aptitude install figlet

The following will create the media2 banner, as above:

figlet -f slant media2

Modifying Message of the Day

Once you are satisfied with the output of figlet, you can have your character graphics banner appear whenever a user uses SSH to access the server, just modify the /etc/motd.tail file with:

sudo figlet -f slant media2 >>/etc/motd.tail

Bingo, whenever a user logs into the media2 server then will see your nifty banner! A little dullness have been bannished.

Installing xmlstarlet, cowsay and fortune

These are the commands we’ll be using to offer some fresh content on every login.

sudo aptitude install xmlstarlet cowsay fortune

Putting it all together

Modify the /etc/bash.bashrc file. This affects all users that use bash as their default shell.

fortune -a | cowsay -f $(ls /usr/share/cowsay/cows/ | shuf | head -n1)

echo -n "word of the day: "
/usr/bin/xmlstarlet sel --net -t -m "/rss/channel/item/description" -v "." "http://dictionary.reference.com/wordoftheday/wotd.rss"

The fortune command pops out a random quip, piped into cowsay, which is configured here with -f to use a random character graphic image. Then, word of the day is sourced from an RSS feed with xmlstarlet.

With everything, here is an example of what will appear when your SSH into your server:

Linux ijuki 2.6.32-x86_64-somewhere #1 SMP Sat Dec 5 16:55:26 UTC 2009 x86_64

                       ___      ___ 
   ____ ___  ___  ____/ (_)___ |__ \
  / __ `__ \/ _ \/ __  / / __ `/_/ /
 / / / / / /  __/ /_/ / / /_/ / __/ 
/_/ /_/ /_/\___/\__,_/_/\__,_/____/ 

Last login: Sun May  2 18:39:14 2010 from
/ Everything that you know is wrong, but \
\ you can be straightened out.           /
       \    ____
        \  /    \
          | ^__^ |
          | (oo) |______
          | (__) |      )\/\
           \____/|----w |
                ||     ||

word of the day: sesquipedalianism: given to using long words.

SSH trick: temporarily return to your local shell

If you are using SSH to access a command shell on a remote system and you would like to temporarily return to a shell on your local system, there is an easy way to do so.

Simply type a tilda (“~”) and control-z.

This will place your SSH session into the background. You will be in a shell on your local system.

You can get the job number of the SSH session with:


Then, to return to the remote session (assuming that the job number you saw when you entered the above command was “1”), enter:

fg 1

Note that the remote shell will not print the prompt, press enter once to see the remote session prompt again.

My remote Subversion dump/tar/rotating file Perl script

This is the script I use to SSH remotely dump Subversion repositories on various servers for which I am responsible.

Before you can use this script, you need to set up SSH so your local cron can access the remote servers without a password.

One thing to note about this script is that it automatically rotates the archived dump files; keeping a fie for the 1st of the week on a month, 1st of the month and 1st of the year.

see: Using Public/Private Key Pairs with SSH

Then, just modify the script for your database/servers (the block @ about line 22).

This will create a series of files over time with daily/weekly/monthly Subversion dump backup tar files. The point is not so much to have every state of every repository, but to grab the daily changes without clobbering the last know good one. More is better, no?

#!/usr/bin/perl -w
# rtar_svn.pl
# by Andrew Ault www.andrewault.net
# No arguments. The program is to be modified to include each Subversion repository to be archived.
# Saves a tar of a remote Subversion dump in a rotating file.
# Of course you have to have SSH authentication already set up.
# This get cron'd daily on my local workstation.
use strict;
use warnings;

use DateTime;

my $fileError;
my $jobError  = 0;
my $jobErrors = "";
my $result;

# Specify a data block for each remote repository to be archived.
my %dumpJobs = (
				 'servername-repositoryname' => {
							'remoteServer' => 'servername',
							'repository'     => 'repositoryname',
							'dumpFilename' => 'servername-repositoryname.dump.svn',
							'svnDumpCmd' => '/usr/bin/svnadmin dump', # find svnadmin on your server
							'tarCmd'       => '/bin/tar', # find tar on your server
				 'servername-repositoryname2' => {
							'remoteServer' => 'servername',
							'repository'     => 'repositoryname2',
							'dumpFilename' => 'servername-repositoryname2.dump.svn',
							'svnDumpCmd' => '/usr/bin/svnadmin dump',
							'tarCmd'       => '/bin/tar',

# Process each specified repository dump/archive job.
for my $dumpJob ( sort keys %dumpJobs ) {
	$fileError = 0;
	my $tarballFilename = "$dumpJobs{$dumpJob}{'dumpFilename'}-" . tarDateSegment() . ".tgz";
	my $svnDumpCmd    = $dumpJobs{$dumpJob}{'svnDumpCmd'};
	my $tarCmd          = $dumpJobs{$dumpJob}{'tarCmd'};
	print "$dumpJob\n";

	my $dumpCommand = "ssh $dumpJobs{$dumpJob}{'remoteServer'} '$svnDumpCmd ";
	$dumpCommand .= "/var/lib/svn/$dumpJobs{$dumpJob}{'repository'} > $dumpJobs{$dumpJob}{'dumpFilename'}'";
	print $dumpCommand . "\n";
	$result = system($dumpCommand );
	if ($result) { $fileError = 1; }

	if ( !$fileError ) {
		my $remoteMakeTarball = "ssh $dumpJobs{$dumpJob}{'remoteServer'} '$tarCmd ";
		$remoteMakeTarball .= "cvfz $tarballFilename $dumpJobs{$dumpJob}{'dumpFilename'}'";
		print $remoteMakeTarball . "\n";
		$result = system($remoteMakeTarball );
		if ($result) { $fileError = 1; }

	if ( !$fileError ) {
		my $downloadCommand = "scp $dumpJobs{$dumpJob}{'remoteServer'}:$tarballFilename .";
		print $downloadCommand . "\n";
		$result = system($downloadCommand );
		if ($result) { $fileError = 1; }

	if ($fileError) {
		$jobError = 1;
		$jobErrors .= "$dumpJob ";
if ($jobError) {
	warn "Errors were encountered: $jobErrors\n";

sub tarDateSegment {
	my $dt = DateTime->now();

	my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time);
	$year += 1900;
	my $dateTime = sprintf "%4d-%02d-%02d %02d:%02d:%02d", $year, $mon + 1, $mday, $hour, $min, $sec;
	my $date     = sprintf "%4d-%02d-%02d",                $year, $mon + 1, $mday;
	my @weekdays = qw( sun mon tue wed thu fri sat );
	my $weekday  = $weekdays[$wday];
	my @months   = qw( jan feb mar apr may jun jul aug sep oct nov dec );
	my $month    = $months[$mon];

	my $weekOfMonth = $dt->week_of_month;

	my $dateTar = "";

	# if the first day of the year, set $dateTar like: 2009-1st
	if ( $yday == 1 ) {
		$dateTar = "$year-1st";

	# if the first day of the month, set $dateTar like: feb-1st
	elsif ( $mday == 1 ) {
		$dateTar = "$month-1st";

	# if the first day of the week, set $dateTar like: mon-1
	# where the number is the week of the month number
	elsif ( $wday == 1 ) {
		$dateTar = "$weekday-$weekOfMonth";

	# otherwise, set the $dateTar like: mon
	else {
		$dateTar = "$weekday";

	# $sec      seconds          54
	# $min      monutes          37
	# $hour     hour             11
	# $mon      month            4
	# $year     year             2009
	# $wday     weekday          3
	# $yday     day of the year  146
	# $isdst    is DST           1
	# $weekday  day of the week  wed
	# $month    month            may
	# $dateTime date and time    2009-05-27 11:37:54
	# $date     date             2009-05-27
	return $dateTar;

=head1 NAME

rtar_svn.pl - Andrew's remote Subversion repository archive program.


    use: rtar_svn.pl


This is a program I wrote to SSH/dump/tar/download/rotate archives of Subversion repositories.



=head1 LICENSE

Use this as you will.

=head1 AUTHOR

Andrew Ault