Sunday, March 10, 2013

Using PERL's MP3::Tag to manipulate the ID3 tags on music files

Argument is a directory




#!/usr/bin/perl

use MP3::Tag; # import module

if(!defined($ARGV[0])) { "die: usage <mp3 dir>"; }

my $dir = $ARGV[0];

@files = <$dir/*.mp3>; # find MP3 files in current directory

# loop over file list
# print tag information

foreach (@files) {

        $mp3 = MP3::Tag->new($_);
        $mp3->get_tags();

        if (exists $mp3->{ID3v2} && exists $mp3->{ID3v1}) {

        #       print $_, "\t", $mp3->{ID3v1}->artist, "\t", $mp3->{ID3v1}->title, "\n";

                print "--------- ID3v2 File: $_ ---------\n";
                print "Artist:\t" . $mp3->{ID3v2}->artist . "\n";
                print "Title:\t" . $mp3->{ID3v2}->title . "\n";
                print "Comment:\t" . $mp3->{ID3v2}->comment . "\n";
                print "Genre:\t" . $mp3->{ID3v2}->genre . "\n";
                print "+++++++++ ID3v1\n";
                print "Artist:\t" . $mp3->{ID3v1}->artist . "\n";
                print "Title:\t" . $mp3->{ID3v1}->title . "\n";
                print "Comment:\t" . $mp3->{ID3v1}->comment . "\n";
                print "Genre:\t" . $mp3->{ID3v1}->genre . "\n";


        }

        $mp3->close();
}

Automating SSH public key distribution using Expect


This script will help automate distribution of a SSH generated key (pub.key) using Expect



Script command line argument = hostname / IP address


#!/bin/bash

PROMP=":~ "
PASS="rootspassword"
USER="root"

PUBKEY=`cat ./pub.key`

/usr/bin/expect -c "
set timeout 180
spawn ssh -q -p 22 $USER@$1

expect {
                yes/no  {
                        sleep 1 ;
                        send "yes"\r;
                        exp_continue
                }
                assword: {
                        sleep 1 ;
                        send "$PASS"\r;
                        }
        }
expect {
                $PROMP       {
                                send \"mkdir ~/.ssh\r\";
                                sleep 1;
                                send \"echo '$PUBKEY' >>~/.ssh/authorized_keys\r\";
                                send \"echo\r\";
                                }
        }
expect {
                $PROMP       {
                                sleep 1;
                                send \"history -c\r\";
                                }
        }
expect {
                $PROMP       {
                                sleep 1;
                                send \"exit\r\";
                                }
        }
"
exit

WebSphere MQ hardcore process cleanup in PERL



Note: this script does a kill -TERM first, then waits to issue a kill -9, terminating processes in the correct order according to the IBM Websphere MQ reference manual.







#!/usr/bin/perl -w
use strict;
##########################################################################
#
# Filename: killallmq.pl
# Version:              1.0
# Date:                 03/28/2012
# Author(s):            Matt Feenstra
# Last updated by:      <>
#
# INFO: This script forcefully terminates MQSeries (WMQ) by:
# 1. Retrieving a list of PIDs for all MQ processes
# 2. For each process, in the correct order:
# a. Send interrupt signal SIGTERM (15)
# b. Wait $sleepwait (10) seconds
# c. If process still exists, issue SIGKILL (9)
# 3. Cleanup all IPC resources belonging to MQM
#
# USAGE: 1. Must be ran as ROOT
# 2. Kill output sent to /tmp/stdio.out and /tmp/stderr.out
#
# NOTES: 1. The initial SIGTERM signal on the processes may
# cause an automatic cascade of process termmination
# due to the nature of MQ process interdependencies.
# 2. It may be helpful to backup and clear out the
# /var/mqm/errors directory such that new AMQERR logs
# are generated on restart.
# 3. When the queue manager is stopped manually in this way,
# FFSTs might be taken, and FDC files placed in
# /var/mqm/errors.  However, this is not a defect in
# the queue manager.
# 4. There is no risk of losing persistent messages.  However
# non-persistent messages, or those with expiry may be
# lost as normal.  Persistent messaging involves a
# complex handshaking protocol that ensures the message
# is safely stored before forwarding.
#
##########################################################################

my $who = `whoami`;
chomp($who);
## if($who ne "root") { die "This program must be ran as root."; }

##########################################################################
# Main()
##########################################################################

my $sleepwait = 10; # seconds to wait after kill 15

&killmq();
&cleanIPC();

##########################################################################
# Subroutines
##########################################################################


# Description: Issues a SIGTERM (15) to the PID
# Requires: PID number
# Returns: N/A
sub kill15cmd {
# signal 15 is a SIGTERM or Termination, which is properly trapped
# by the WMQ code.  We always try this first.
my $pid = shift;
system("kill -15 $pid 1>>/tmp/stdio.out 2>>/tmp/stderr.out");
sleep($sleepwait);
}

# Description: Issues a SIGKILL (9) to the PID
# Requires: PID number
# Returns: N/A
sub kill9cmd {
my $pid = shift;
print "\tInfo:\t\tForcefully removing $pid..\n";
system("kill -9 $pid 1>>/tmp/stdio.out 2>>/tmp/stderr.out");
}

# Description: Determines if a Process ID number is running
# Requires: PID number
# Returns: Boolean (true/false)
sub isproc {

my $pid = shift;
my @procs = `ps -eo pid,args`;
chomp(@procs);

foreach(@procs) {
if($_ =~ /$pid/) {
return(1);
}
}
return(0);
}

# Description: Issues an IPC RM to remove stale Inter Process Communication
# Websphere MQ utilizes System V (SysV) IPC resources which are
# zombied once the parent process is killed.
# Requires: N/A
# Returns: N/A
sub cleanIPC {

my $userid = "mqm";
my @ipcs_s = `ipcs -s`;
my @ipcs_m = `ipcs -m`;
my @ipcs_q = `ipcs -q`;

print "\n***\tStarting IPC Cleanup\t***\n";

# Semaphores
foreach(@ipcs_s) {
if($_ =~ /\S+\s+(\S+)\s+($userid)/) {
#print "semid = $1\towner = $2\n";
print "\tInfo:\t\tRemoving Semaphore ID $1\n";
system("ipcrm -s $1");
}
}
     
# Shared Memory
foreach(@ipcs_m) {
                if($_ =~ /\S+\s+(\S+)\s+($userid)/) {
                        #print "memid = $1\towner = $2\n";
print "\tInfo:\t\tRemoving Shared Memory ID $1\n";
system("ipcrm -m $1");
                }
        }

# IPC SysV Message Queues (not to be confused with MQ)
        foreach(@ipcs_q) {
                if($_ =~ /\S+\s+(\S+)\s+($userid)/) {
                        #print "qid = $1\towner = $2\n";
print "\tInfo:\t\tRemoving Message Queue ID $1\n";
system("ipcrm -q $1");
                }
        }
}

# Description: This is the parent subroutine that actually retrieves and
# kills the WMQ processes in the correct order.
# Requires: N/A
# Returns: STDOUT
sub killmq() {

my @procs = `ps -eo pid,args`;
chomp(@procs);
my @sortedprocs = sort(@procs);
my @mqprocs;
my @mqpids;
my $numpids;

foreach(@sortedprocs) {

if($_ =~ /(\d+)\s+.*?(amq.....)/) {
#print "found: $1\t$2\n";
push(@mqpids, $1);
push(@mqprocs, $2);
}
if($_ =~ /(\d+)\s+.*?(runmq...)/) {
#print "found: $1\t$2\n";
push(@mqpids, $1);
push(@mqprocs, $2);
}
}

$numpids = @mqpids;

# Proper kill order listed in ranked priority:
#
# runmqlsr
# runmqchi
#
# amqzmuc0      Critical process manager
# amqzxma0      Execution controller
# amqzfuma      OAM process
# amqzlaa0      LQM agents
# amqzlsa0      LQM agents
# amqzmgr0      Process controller
# amqzmur0      Restartable process manager
# amqrmppa      Process pooling process
# amqrrmfa      The repository process (for clusters)
# amqzdmaa      Deferred message processor
# amqpcsea      The command server

print "\n***\tStarting Termination Sequence\t***\n";
print "\n***\tInfo:\t\tTerminating Listeners, Channel Initiators, and default MQ broker..\t***\n";
for(my $i = 0; $i < $numpids; $i++) {
if($mqprocs[$i] =~ /runmq/) {

print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
kill15cmd($mqpids[$i]);
if(&isproc($mqpids[$i])) {
print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
&kill9cmd($mqpids[$i]);
}
else {
print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n-\n";
}

splice(@mqpids, $i, 1);
splice(@mqprocs, $i, 1);
$numpids--;
$i--;

}

}
print "\n***\tInfo:\t\tTerminating Critical Process Manager (amqzmuc0)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqzmuc./) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }

                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

print "\n***\tInfo:\t\tTerminating Execution Controller (amqzxma0)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqzxma./) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }


                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating OAM process (amqzfuma)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqzfuma/) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }


                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating LQM agents1 (amqzlaa0)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqzlaa./) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }


                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating LQM agents2 (amqzlsa0)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqzlsa./) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }

                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating Process Controller (amqzmgr0)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqzmgr./) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }

                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating Restartable Process Manager (amqzmur0)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqzmur./) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }

                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }


        print "\n***\tInfo:\t\tTerminating Process Pooling Process (amqrmppa)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqrmppa/) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }

                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating The Repository Process for clusters (amqrrmfa)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqrrmfa/) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }

                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating Deferred Message Processor (amqzdmaa)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqzdmaa/) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }

                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating The Command Server (amqpcsea)\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {
                if($mqprocs[$i] =~ /amqpcsea/) {

                        print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                        kill15cmd($mqpids[$i]);
                        if(&isproc($mqpids[$i])) {
                                print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                                &kill9cmd($mqpids[$i]);
                        }
                        else {
                                print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                        }

                        splice(@mqpids, $i, 1);
                        splice(@mqprocs, $i, 1);
                        $numpids--;
                        $i--;
                }
        }

        print "\n***\tInfo:\t\tTerminating UNKNOWN processes\t***\n";
        for(my $i = 0; $i < $numpids; $i++) {

                print "-\n\tInfo:\t\tSending termination signal to process \"$mqprocs[$i]\" PID $mqpids[$i]..\n";
                kill15cmd($mqpids[$i]);
                if(&isproc($mqpids[$i])) {
                        print "\tWarning:\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] is still running..\n";
                        &kill9cmd($mqpids[$i]);
                }
                else {
                        print "\tInfo:\t\tProcess \"$mqprocs[$i]\" PID $mqpids[$i] terminated gracefully.\n";
                }

                splice(@mqpids, $i, 1);
                splice(@mqprocs, $i, 1);
                $numpids--;
                $i--;
        }


} ## end killmq()

Automated remote Linux Login Expect script

The following script is my example of using Expect to automate login and command execution from a Linux box to another server using SSH

Script command line argument = hostname / IP address



#!/usr/bin/expect

set LOGDIR   "./"

###########################################################################

set USER matt
set PASS mattspassword
set HOST [lindex $argv 0]
set PORT 22
set TIMEOUT 180
set PROMPT "# "

###########################################################################

log_file -a $LOGDIR/$HOST.log

catch { spawn ssh -p $PORT $HOST -l $USER }
set timeout $TIMEOUT

expect {

        timeout         {
                        send_user "\nTIMED OUT $TIMEOUT seconds\n";
                        exit 0;
                        }

        "yes/no"        {
                        sleep 1;
                        send "yes\r";
                        exp_continue;
                        }

        "*assword:"     {
                        sleep 1;
                        send "$PASS\r";
                        }
}


expect {

        "*assword:"     {
                        sleep 1;
                        send_user "\nWRONG PASSWORD or LOGIN DISABLED\n";
                        exit 0;
                        }

        # This is where we do the work

        "$PROMPT"       {
                        sleep 1;
                        send "\r";
                        expect "$PROMPT";
                        send "uname -a\r"
                        expect "$PROMPT";
                        send "echo \"my public ssh key infoz\" >> ./tempfile.cert\r"
                        expect "$PROMPT";
                        send "exit\r";
                        exit 1;
                        }
}

Saturday, March 9, 2013

iTerm2 Multiple Server Window applescript

To open multiple server terminals with iTerm2 automatically (in tabs), use an applescript with a list as shown below.  This is especially handy for admin tasks broadcast to all servers with the Command-Shift-I hotkey.





MyServers.list looks like:

username@server1.com
username2@server2.com



Run with:
osascript ./MyServers.scpt



AppleScript (MyServers.scpt):




-- Launch iTerm and log into multiple servers using SSH


tell application "iTerm"

activate

-- Read serverlist from file path below

set Servers to paragraphs of (do shell script "/bin/cat $HOME/itermstuff/MyServers.list")

repeat with nextLine in Servers

-- If line in file is not empty (blank line) do the rest

if length of nextLine is greater than 0 then

set server to "nextLine"
set term to (current terminal)

-- Open a new tab
tell term
launch session "Default Session"
tell the last session
write text "ssh -p 22 " & nextLine
-- sleep to prevent errors if we spawn too fast
do shell script "/bin/sleep 0.01"
end tell
end tell
end if
end repeat

-- Close the first tab since we do not need it

terminate the first session of the current terminal
end tell

Ruby + Gems Force Install on Suse Enterprise Linux







# install GNU compiler (and required glibc libraries)

yast -i gcc

# install / overwrite system libraries

rpm -iv --force ./files/openssl-0.9.8e-22.el5_8.4.x86_64.rpm
rpm -iv --force ./files/gdbm-1.8.0-26.2.1.el5_6.1.x86_64.rpm

rpm -ivh --force ./files/zlib-1.2.3-4.el5.x86_64.rpm
rpm -ivh ./files/zlib-devel-1.2.3-4.el5.x86_64.rpm

rpm -ivh ./files/db4-4.3.29-10.el5_5.2.x86_64.rpm
rpm -ivh ./files/libtermcap-2.0.8-46.1.x86_64.rpm

# install ruby

cd ./files
tar -zxvf ruby-1.8.7-p357.tar.gz
cd ruby-1.8.7-p357
make clean
./configure
make
make install
cd ../..

# install ruby-libs

rpm -ivh ./files/ruby-libs-1.8.7.299-7.el5.x86_64.rpm

# install ruby-devel

rpm -ivh ./files/ruby-devel-1.8.7.299-7.el5.x86_64.rpm

# install rubygems

cd ./files
tar -zxvf rubygems-1.5.2.tgz
cd rubygems-1.5.2
ruby setup.rb
cd ../..


# install gems

gem install ./files/rbx-require-relative-0.0.9.gem
gem install ./files/linecache-0.46.gem
gem install ./files/columnize-0.3.6.gem
gem install ./files/rake-0.8.7.gem
gem install ./files/ruby-debug-base-0.10.4.gem
gem install ./files/ruby-debug-0.10.4.gem