Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

Install ikiwiki in an arbitrary directory

ikiwiki doesn't install using PREFIX= like normal programs (it still wants to put stuff in /etc/ikiwiki).

perl Makefile.PL DESTDIR=/path/to/install/dir PREFIX="" INSTALL_BASE="/"

pcregrep - UTF-8 aware grep replacement

# we first have to download, compile & install the PCRE library, cf. http://www.pcre.org/pcre.txt
# requirement: Xcode, http://developer.apple.com/tools/xcode/index.html

cd ~/Desktop
/usr/bin/curl -L -O http://downloads.sourceforge.net/pcre/pcre-7.7.tar.gz
/usr/bin/tar -xzf pcre-7.7.tar.gz
cd pcre-7.7
./configure --help
./configure --prefix=/usr/local --enable-utf8 --enable-unicode-properties
# for Intel Macs, see http://hivelogic.com/articles/2005/12/ruby_rails_lighttpd_mysql_tiger
#./configure --prefix=/usr/local --enable-utf8 --enable-unicode-properties CFLAGS=-O1
/usr/bin/make
/usr/bin/sudo /usr/bin/make install 


ls -l /usr/local/bin/pcregrep
stat -x /usr/local/bin/pcregrep

pcregrep --version
pcregrep --help
pcregrep --help | pcregrep -i 'utf-?8'
pcregrep --help | pcregrep -i multiline

man pcregrep
man pcrepattern
man pcretest
man perlretut

man pcregrep | less -p utf-8
man pcregrep | less -p multiline
man perlretut | less -p 'single line and multi'

open /usr/local/share/doc/pcre/html/pcregrep.html


# check if character set encoding of Terminal.app is set to UTF-8
if [[ "$(/usr/bin/defaults read com.apple.Terminal StringEncoding)" != "4" ]]; then 
   echo 'Terminal.app does not use UTF-8 character set encoding!'
   exit 1
fi


utf8str=$'caf\303\251'

printf $utf8str | /usr/bin/egrep -o '.'
printf $utf8str | /usr/local/bin/pcregrep -o '.'
printf $utf8str | /usr/local/bin/pcregrep -ou '.'     # UTF-8 aware
printf $utf8str | /usr/local/bin/pcregrep -ou 'f.$'

printf $utf8str | /usr/bin/egrep -o '.' | wc -l
printf $utf8str | /usr/local/bin/pcregrep -o '.' | wc -l
printf $utf8str | /usr/local/bin/pcregrep -ou '.' | wc -l     # UTF-8 aware


#---------------------------------------------


# cf. also The Heirloom Project, http://heirloom.sourceforge.net
# download & install from http://homepage.mac.com/stefan.tramm/iWiki/HeirloomNotes.html

# backup ~/.bash_login with time stamp in filename
/bin/cp -ip "${HOME}/.bash_login"{,".orig-$(/bin/date +%Y-%m-%d-%H.%M.%S)"}


# To use the Heirloom tools insert the following statements into your ~/.profile or ~/.bash_login:

/bin/cat >> "${HOME}/.bash_login" <<-'EOF'

# Heirloom userland
# http://homepage.mac.com/stefan.tramm/iWiki/HeirloomNotes.html

HEIRLOOM=/opt/heirloom
if [[ -d $HEIRLOOM ]]; then
  export HEIRLOOM
  PATH=$PATH:$HEIRLOOM/5bin
else
  unset HEIRLOOM
fi

EOF


# make Heirloom source the ~/.bash_login shell functions
/bin/ls -lo /opt/heirloom/etc/5.rc
/usr/bin/sudo /bin/cp -ip /opt/heirloom/etc/5.rc{,.orig}   # backup
/usr/bin/sudo /bin/chmod 766 /opt/heirloom/etc/5.rc

# ~/.bash_login should "source ~/.bashrc" and "bind -f ~/.inputrc"
/usr/bin/sudo echo 'source ~/.bash_login' >> /opt/heirloom/etc/5.rc

/usr/bin/sudo /usr/sbin/chown root:admin /opt/heirloom/etc/5.rc
/usr/bin/sudo /bin/chmod 644 /opt/heirloom/etc/5.rc
/bin/ls -lo /opt/heirloom/etc/5.rc

# delete the last (added) line
#/usr/bin/sudo /usr/bin/sed -i '' '$,$d' /opt/heirloom/etc/5.rc

/usr/bin/open -e /opt/heirloom/etc/5.rc


source ~/.bash_login


/usr/bin/open -e /opt/heirloom/README
/usr/bin/open /opt/heirloom/{,{etc/,5bin/}}      # open three directories in one go
/usr/bin/open /opt/heirloom/doc/{,doctools}
/usr/bin/open /opt/heirloom/doc/{,doctools/{,quickstart.pdf}}  
/usr/bin/open /opt/heirloom/doc/doctools/quickstart.pdf       # explore Heirloom troff

5 man intro | less -p 'Multibyte character encodings'
5 man sh | less
5 man tsort | less
5 whodo
5
man pgrep
pgrep sh
pgrep bash
man bfs | less  # bfs - big file scanner


/usr/bin/stat -x $HEIRLOOM/5bin/5
/usr/bin/stat -f '%N:  %HT%SY' $HEIRLOOM/5bin/5
/usr/bin/stat -f $'%N:  \e[1m%HT%SY\e[m' /opt/heirloom/bin/tsort
/usr/bin/stat -f $'%N:  \e[1;31m%HT\e[m%SY' /opt/heirloom/5bin/awk


/usr/bin/open http://heirloom.sourceforge.net/man/grep.1.html
5 man grep | less


5

utf8str=$'caf\303\251'
echo $utf8str

printf "${utf8str}\n" | /usr/local/bin/pcregrep -u 'f.$'
printf "${utf8str}\n" | /opt/heirloom/5bin/grep 'f.$'
printf "${utf8str}\n" | /opt/heirloom/5bin/posix/grep -E -e 'f.$'

flexbackup perl script running as a cron job

// Not so much code here as a record of events and observations
// The summary of countless hours of 'fun' tracking down reasons and solutions for flexbackup not running happily as a cron job.

Flexbackup is a well tried script to automate backup to tape of fixed-disk. It will run in Linux, BSD and Solaris (using gnu findutils [tar and find]) .

It uses perl and shell scripting to elegantly backup data 'sets'.

It uses a configuration file flexbackup.conf stored in /etc

In certain circumstances this will not run cooperatively as a 'cron' job.

This note refers to dealings with an aging Sun system running Solaris. It is considered that these notes will apply equally to many other areas. This is the result of a lot of searching and testing to find a workable solution.

The configuration was tried and tested using the terminal as direct input for commands but failed when run as a 'cron' job.

Interesting elements in my flexbackup.conf are:

##################### /etc/flexbackup.conf ################
$type = 'afio';

$compress = 'gzip'; # one of false/gzip/bzip2/lzop/zip/compress/hardware
$compr_level = '4'; # compression level (1-9) (for gzip/bzip2/lzop/zip)

# Buffering program - to help streaming
$buffer = 'false'; # one of false/buffer/mbuffer

$device = '/mnt/backup'; #the backup raid system on another machine in another office

# I had trouble with this and on an error from cron (it reported that ssh wasn't in the path) I put in the full path...however flexbackup script mistreated that on a content test so I added it as a path below
$remoteshell = 'ssh'; # command for remote shell (rsh/ssh/ssh2)

# I kept this as recording dates as it is useful when they are moved or deleted
$staticfiles = 'false';

$logdir = '/mnt/backup/log/flexbackup_log'; # directory for log files
$comp_log = 'gzip'; # compress log? false/gzip/bzip2/lzop/compress/zip
$staticlogs = 'false'; # static log filenames w/ no date stamp
$prefix = ''; # log files will start with this prefix
$tmpdir = '/mnt/backup/tmp'; # used for temporary refdate files, etc
$stampdir = '/mnt/backup/stamps'; # directory for backup timestamps
$index = '/mnt/backup/log/flexbackup_index'; # DB filename for tape indexes
$keyfile = '00-index-key'; # filename for keyfile if archiving to dir
$sprefix = ''; # stamp files will start with this prefix

# Example: If GNU tar is called "gtar" on your system:
# $path{'sudo'} = '/usr/local/bin/sudo'; # see note below
$path{'tar'} = 'sudo /usr/local/bin/tar';
$path{'pax'} = 'sudo /bin/pax';
#
# Or can be used to "sudo" certain commands. Examples:
$path{'find'} = 'sudo /usr/local/bin/find';
# $path{'dump'} = 'sudo dump';
# $path{'afio'} = 'sudo -u nonrootuser afio';
$path{'afio'} = 'sudo /usr/local/bin/afio';
$path{'ssh'} = '/usr/local/bin/ssh';
#

############################ /etc/sudoers ##############

#additions

Cmnd_Alias FLEXBACKUP = /bin/flexbackup, /bin/pax, /usr/local/bin/find, /usr/local/bin/tar, /bin/gzip, /usr/local/bin/afio

flexbackupuser ALL = NOPASSWD: FLEXBACKUP

############################ end ###################

################### comments and notes ##############

Use of crontab

Check and/or amend the editor otherwise you will get good old ed ... aagh!

$export EDITOR=vi
$sudo crontab -e

By using this command the cron daemon will autmatically be restarted to pickup the amendments.

Initially, knowing that cron disliked output even though it 'might' send it by mail...I used the following command...(for a 1:45pm test after a successful full starting backup from the terminal.

In crontab...

45 13 * * 1-5 /usr/local/bin/sudo /bin/flexbackup -set test_set -level incremental > /dev/null 2>&1

Finally realising problems I redirected output to a file using:

50 13 * * 1-5 /usr/local/bin/sudo /bin/flexbackup -set test_set -level incremental 2>&1 >> /path/to/tester.log

Note that sudo lived in /usr/local/bin.

Long story cut short...

cron operates out of its own (very very limited environment. In other words amongst other things its PATH is strictly limited. For the Sun Solaris this default path is detailed here and usually for all root jobs is restricted to /usr/sbin and /usr/bin.

http://docs.sun.com/app/docs/doc/816-1055/6m7gh31f1?a=view

I tried amending many of the paths on flexbackup.conf including setting these (which failed variously):

DO NOT USE FOR INFORMATION ONLY - THESE DO NOT WORK
$path{'sudo'} = '/usr/local/bin/sudo'; # see note below
$path{'tar'} = '/usr/local/bin/sudo /usr/local/bin/tar';
$path{'find'} = '/usr/local/bin/sudo /usr/local/bin/find';
$path{'afio'} = '/usr/local/bin/sudo /usr/local/bin/afio';
$path{'ssh'} = '/usr/local/bin/ssh';

Ultimately, I was concerned about opening too many additional paths for cron so I simply copied sudo from /usr/local/bin to /usr/bin (ironically I used sudo to copy sudo).

I didn't want to copy over the other binaries as most of them were late additions to the system and in particular would conflict with tar and find. The binaries listed in /usr/local/bin for example were gnu tar and find etc.

I could then delete the path to sudo and successfully created a sequence of backups using cron.

The final cron instruction therefore can also change the location of sudo to /usr/bin/sudo but it exists in both directories now.

For further information.

To list contents (it creates its own output log file in the current directory and rushes a copy to stdout to test your speed reading skills!

flexbackup -list name_of_the_archive.afio-gz

Interestingly this log file is suffixed with the date-time of the enquiry to avoid confusion with other logs.

To extract a single known file:

flexbackup -extract name_of_the_archive.afio-gz -onefile name_of_the_requested_file

...and there it is in the current directory. At last!

Restore?
Not tried yet

full means full/all
differential means only the files changed/added since the last backup (of that set)
incremental means only the files changed/added since the last backup

So differential is ideal for weekly catch all backups and incremental for daily backups.

An idealised makeup is a monthly full, with incrementals everyday then a weekely differential, then delete the incrementals and start them again. Then do another full and rotate the last full to tape or another partition.

To check space used by directories use:

sudo du -sk dir_name

or in a current directory sud du -sk *

(Output is in kb)

I achieved about 50% reduction in size but that obviously depends on numbers of uncompressed items.

I am happy with afio for integrity of individual files. I wanted to try pax but it failed. I never examined the reason.

I hope this helps somebody. It took me absolutely ages to sort out but I really wanted to get flexbackup working completely.

Afio used is version 2.5

Quick and dirty perl to get the last directory name from a long path

// description of your code here

perl
#sloppy but quick use of backticks
my $dir = `/bin/pwd`;
chomp $dir;
###########################
my @Dir = split(/\//, $dir); #split on the slash 

my $current_directory=pop(@Dir); #being the last element
my $penultimate_directory = pop(@Dir); #now this is the penultimate element
my $pre_pen_dir = pop(@Dir); #now this is the last element which was the pre-penultimate element

perl pack fixed width iges file

// create a fixed width iges file (should be 80 characters I think) - working notes

while (<>) {
        my($date, $desc, $income, $expend) = unpack("A10xA27xA7xA*", $_);
        $tot_income += $income;
        $tot_expend += $expend;
    }

    $tot_income = sprintf("%.2f", $tot_income); # Get them into 
    $tot_expend = sprintf("%.2f", $tot_expend); # "financial" format

    $date = POSIX::strftime("%m/%d/%Y", localtime); 

    # OK, let's go:

    print pack("A10xA27xA7xA*", $date, "Totals", $tot_income, $tot_expend); 

with amendments noted here:

    $tot_income = sprintf("%.2f", $tot_income); 
    $tot_expend = sprintf("%12.2f", $tot_expend);
    $date = POSIX::strftime("%m/%d/%Y", localtime); 
    print pack("A11 A28 A8 A*", $date, "Totals", $tot_income, $tot_expend);  

gives:

    01/28/2001 Flea spray                                 24.99
    01/29/2001 Camel rides to tourists     1235.00
    03/23/2001 Totals                      1235.00      1172.98  

perl hash sort and ordinary sort

// sort arrays or hashes
@sorted = sort { $a <=> $b } @not_sorted # numerical sort  

or

@sorted = sort { $a cmp $b } @not_sorted # ASCII-betical sort  

or better 

@sorted = sort { lc($a) cmp lc($b) } @not_sorted # alphabetical sort 

Get a list of hash keys sorted by value.

@sorted = sort { $hash{$a} cmp $hash{$b} } keys %hash;

Get a reverse sort of a list.

@sorted = sort { $b cmp $a } @list; Which can also be done with @sorted = reverse sort { $a cmp $b } @list; 

also for this:

$fileNames[0] = logfile200704050000
$fileNames[1] = logfile200704050050
$fileNames[2] = logfile200704050812
$fileNames[3] = logfile200704050225

use:
@sorted = sort { substr($a,8,12) < = > substr($b,8,12) } @fileNames;

If you have a list of hash refs and you want to sort by two values (for example, sort primarily by people's ages, but if the ages are the same, sort alphabetically), do something like this:

@sorted = sort { ($a->{age} $b->{age}) || ($a->{name} cmp $b->{name}) } @not_sorted;


Fix for the Codesamples of the Haxe/Neko Book from Wrox

- downloads the zip
- unzips the file and all nested zips
- removes all the spaces in filenames and folders and replaces it with "_"

#!/usr/bin/perl
# 
# Fix for the Codesamples of the Haxe/Neko Book from Wrox
# ======================================================
# - download the zip
# - unzip the file and all nested zips
# - remove all the spaces in filenames and folders and re
# replace it with "_"
#
# Needs to be installed on your machine:
# - 'unzip' program (can be configured)
# - 'wget' program
#
# ben.aurel@gmail.com,25.04.08

use strict;
use warnings;

# -------------- Configuration ---------------------
my $dir = ".";

my $unzipcmd = "unzip";

my $URL_of_haxe_book = "http://media.wiley.com/product_ancillary/37/04701221/DOWNLOAD/9780470122136_code.zip";

# -------------- Do not change ---------------------
my @a=split(/\//,$URL_of_haxe_book);
my $zip_file_url = $a[$#a];
my $zip_file= 'haxe_neko_book.zip';

system("wget $URL_of_haxe_book") == 0 or die "Couldn't download the book";
rename "$zip_file_url","$zip_file" or die "Couldn't rename the downloaded zip file $! \n";
system("unzip $zip_file") == 0 or die "Couldn't unzip the book";





&recurse_extract($dir);

sub recurse_extract() {
	my $dir = shift;
	opendir my $dh , $dir  	 
		or die "error: $! \n"; 
	while ($_ = readdir $dh) {
		next if /^\.{1,2}$/;
		my $path = "$dir/$_";
                my $filename= "$_";
		print "in path: $path \n" if -f $path;
                my $filename2 = &remove_space_in_filename($filename);
                if ($filename2 ne $filename) {
                   rename "$dir/$filename","$dir/$filename2" or warn "Unable rename: $!\n";
                }      
                if ($filename2 =~ m/\.zip$/) {
                   &unzip_file("$dir", "$filename2");
                }
                $path = "$dir/$filename2";
                print "call recurse with $path\n";
                &recurse_extract($path) if -d $path;

	}
                                          
	print "in dir: $dir \n" or print "error - $! \n";
}

&recurse_filenames($dir);

sub recurse_filenames() {
	my $dir = shift;
	opendir my $dh , $dir  	 
		or die "error: $! \n"; 
	while ($_ = readdir $dh) {
		next if /^\.{1,2}$/;
		my $path = "$dir/$_";
                my $filename= "$_";
		print "in path: $path \n" if -f $path;
                my $filename2 = &remove_space_in_filename($filename);
                if ($filename2 ne $filename) {
                   rename "$dir/$filename","$dir/$filename2" or warn "Unable rename: $!\n";
                }      
                $path = "$dir/$filename2";
                &recurse_filenames($path) if -d $path;

	}
                                          
	print "in dir: $dir \n" or print "error - $! \n";
}


sub remove_space_in_filename() {
   my $file_w_space = shift;

   (my $file_nospace = $file_w_space) =~ s/\s/_/g;
   return $file_nospace;
}

sub unzip_file() {
   my $dir = shift;
   my $filename = shift;
   my $path2zip = "$dir/$filename";
   system("$unzipcmd $path2zip -d $dir") == 0 or die "Couldn't unzip $path2zip";

}



Rename files by reordering existing data (regular expression capturing submatches)

Takes all files in a directory that end with .jpg and that have a filename with format DD_MM_YY-HHMM.jpg and renames them as YYMMDDHHMM.jpg

#alter the regex to suit your needs, each () will return a submatch
my $regex = qr!(\d\d)[-](\d\d)[-](\d\d)[_](\d\d\d\d)!;

while(<*.jpg>) {
	$oldname = $_;
	if ($oldname=~m/$regex/) {

		#$1,$2,etc are submatchs
		rename $oldname,$3.$2.$1.$4.".jpg";
	}
}

s_nodelist.pl

Liste les managed nodes installés sur le serveur OVOW

#
# POLICY: 
#
# CONFIGURATION: N/A
#
# PARAMETRES D'APPEL: N/A
#
# SORTIE: mail
#
# FICHIERS ENTREE:
#
#
# FICHIERS SORTIE:
#
#
# COMMENTAIRES:
#	
#
#
# MODIFICATIONS:
# 15/01/2008    Ajout de trace pour debugging => eval/die
#
#

use strict;
use Getopt::Std;
use Win32;
use Win32::OLE qw( in );
use Win32::OLE('in');

my $RepositoryFile = "\\\\ilbur001\\SrvIBP\\Projet\\Surv_HPOVO (P9SUR024)\\Production\\log\\NodesOn$ENV{COMPUTERNAME}.txt";

if ( $ENV{COMPUTERNAME} =~ /HPO001/ ) {
	$RepositoryFile = "\\\\ilbur001\\SrvIBP\\Projet\\Surv_HPOVO (P9SUR024)\\Production\\log\\old\\NodesOn$ENV{COMPUTERNAME}.txt";
}


my $server      = '';    # connect to local machine
my $debug 	= 'TRUE';
my $log_file    = "$ENV{OVINSTALLDIR}"."temp/s_nodelist.log";

sub TRACE {
	my $f = shift;
	logger( 'TRACE' . "\t" . $f, @_ );
}

sub ERROR {
	my $f = shift;
	logger( 'ERREUR' . "\t" . $f, @_ );
}

sub logger {
	my $f = shift;
	my $msg = sprintf( ts() . "\t" . $f . "\n", @_ );
	print {*STDOUT} $msg;
	open my $desc_log_file , '+>>', $log_file ;
	print {$desc_log_file} $msg ;
	close $desc_log_file;
}

sub ts {
	my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
	  localtime( time() );
	return (
		sprintf(
			'%04d-%02d-%02d %02d:%02d:%02d',
			$year + 1900,
			$mon + 1, $mday, $hour, $min, $sec
		)
	);
}


eval {
	open my $file, '>', "$RepositoryFile" or die "Can't open file $RepositoryFile: $!\n";
#--------------------------------
# Récupère un objet SWbemLocator
#-------------------------------
	my $lobj = Win32::OLE->new('WbemScripting.SWbemLocator')
		or die "can't create locator object: " . Win32::OLE->LastError() . "\n";
#----------------------------------------------------------------
# Prépare une connexion avec un niveau de sécurité "impersonate"
#---------------------------------------------------------------
	$lobj->{Security_}->{impersonationlevel} = 3;

#-----------------------------------
# Connexion à l'objet SWbemServices
#----------------------------------
	my $sobj = $lobj->ConnectServer( $server, 'root\hewlettpackard\openview\data' )
		or die "can't create server object: " . Win32::OLE->LastError() . "\n";

	my $wmiquery = "Select * from OV_ManagedNode";

	print "\$wmiquery=$wmiquery\n" if ($debug);

	my $nodelist = $sobj->ExecQuery($wmiquery)
		or die "La requête a echouée " . Win32::OLE->LastError() . "\n";

	my ( $sourceName, $count );
	my ( @listenoeud, @sortedlist );
	foreach my $node ( in $nodelist )
	{
		#next if ( $node->{Caption} =~ m/(Management Server)/ );
		$sourceName = $node->{PrimaryNodeName};
		push @listenoeud, $sourceName;
	}
	@sortedlist = sort @listenoeud;
	foreach my $node (@sortedlist)
	{
		#next if ( $node =~ /ESX/ );
		print {$file} $node."\n" ;
		$count++;
	}

	close $file;

	TRACE($count . " Managed Nodes listed\n");
};
if ( $@ ) {
	ERROR($@);
}

s_CorRegKeyAgt.pl

Assure la cohérence de la clef de registre de l'agent et du 'Full computer Name'

# $Id: s_CorRegKeyAgt.pl 29 2007-08-14 14:10:01Z jcde $
# $Date: 2007-08-14 16:10:01 +0200 (mar., 14 août 2007) $
# 
# PERL
# $HeadURL: svn://localhost/Perl_OVOW/s_CorRegKeyAgt.pl $ v1.0
#
# FONCTION: Assure la cohérence de la clef de registre de l'agent et du 'Full computer Name'
#
# POLICY: N/A
#
# CONFIGURATION: N/A
#
# PARAMETRES D'APPEL:  
#
# SORTIE: message 
#
#
# FICHIERS ENTREE: 
#
#
# FICHIERS SORTIE: 
#
#
# COMMENTAIRES:
#	
#
# MODIFICATIONS:
#
# $Author: jcde $
#

use strict;
use warnings;
use Win32::TieRegistry ( Delimiter=>"/", ArrayValues=>1 );



#my $Registry->Delimiter("/"); # Set delimiter to "/".

my $AgentKey = $Registry->{"LMachine/Software/Hewlett-Packard/Openview/ITO/"};

print "ITO Reg Key Value:".$AgentKey->GetValue('HostName')."\n";

my $HNameKey = $Registry->{"LMachine/System/CurrentControlSet/Services/TCPIP/Parameters/"};

my $Domain = $HNameKey->GetValue('Domain');
my $HstName = $HNameKey->GetValue('HostName');

#print $HNameKey->GetValue('Domain')."\n";
my $sep = ($Domain) ? "." :'';
#print $HNameKey->GetValue('HostName')."\n";

print "Full computer Name Value:".$HstName.$sep.$Domain."\n";

if ( $AgentKey->GetValue('HostName') ne $HstName.$sep.$Domain ) {
    print "Mismatch detected !!";
    $Registry->{"LMachine/Software/Hewlett-Packard/Openview/ITO/Hostname"} = $HstName.$sep.$Domain;
    print "Modification done !\n";
    system('opcagt -k');
    print "Agent stopped !\n";
    system('opcagt -start');
    print "Agent started !\n";
}
else {
	print "OK !!\n";
}