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();
}
Matt Feenstra is an Architect and Developer, living and working in Palm Desert, CA
Sunday, March 10, 2013
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;
}
}
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
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
Subscribe to:
Posts (Atom)