J
Jorge
I have a Linux directory full of shell scripts (~100 scripts with
average
size of ~60 lines) with many of them calling other scripts as
depencencies.
Not being the author of the scripts and with the immediate need to
become familiar with
the overall scope of this script directory, I needed to create a cross-
reference chart
that shows what script depends on what other script.
My Perl script (below) works in terms of doing what I need, however,
IMO, it appears to run a bit slow. I timed it at ~3.5 sec. Possibly
that is it's max performance but something tells me (from other Perl
script experiences) this one just isn't up to speed.
I would appreciate any ideas or comments.
Thanks, Jorge
#!/usr/bin/perl -l
use strict;
use warnings;
&scripts_dir('/some/dir/that/holds/scripts');
sub scripts_dir {
# set some vars
my $dir = shift;
my(@paths, $paths, @scripts, $scripts, $string);
my($lines, $leaf, $header, $header2);
local($_);
# check dir can be opened for read
unless (opendir(DIR, $dir)) {
die "can't open $dir $!\n";
closedir(DIR);
return;
}
#
# read dir, skip over system files and bak files
# build array of script names
# build array of full-path script names
#
foreach (readdir(DIR)) {
next if $_ eq '.' || $_ eq '..' || $_ =~ /\.bak$/;
push(@scripts, $_);
$paths = $dir."/".$_;
push(@paths, $paths);
}
closedir(DIR);
# open ouput file, format and print headers
open OUT, ">output" or die "cannot open output for writing $! ...
\n";
$header = sprintf("%-25s%-25s%s", "SCRIPT NAME", "FOUND IN",
"USAGE");
$header2 = sprintf("%-25s%-25s%s", "===========", "========",
"=====");
print OUT $header;
print OUT $header2;
# loop through each script name
foreach $scripts(@scripts){
# loop through each script in directory
foreach my $paths(@paths){
# get last leaf of script being searched --
# if it matches itself; skip
$leaf = get_leaf($paths);
if($scripts eq $leaf) { next;}
# open each script for searching
open F, "$paths" or die "cannot open $paths for reading
$! ...\n";
while(my $lines = <F>) {
# -l switch in place
chomp($lines);
# search for matches to the commonly-used command
syntax
if($lines =~ /\$\($scripts / || $lines =~ /\`
$scripts /){
# format to line up with headers
$string = sprintf("%-25s%-25s%s", $scripts, $leaf,
$lines);
# print to file
print OUT $string;
}
}
}
}
# close I/O streams
close(F);
close(OUT);
}
#======================
# subroutine get_leaf
#======================
sub get_leaf
{
# get arg(s)
my($pathname) = @_;
# split on leafs
my @split_pathname = split( /[\\\/]/, $pathname);
# grab last leaf
my $leaf = pop( @split_pathname );
# return bare script name (leaf)
return( $leaf );
}
__END__
average
size of ~60 lines) with many of them calling other scripts as
depencencies.
Not being the author of the scripts and with the immediate need to
become familiar with
the overall scope of this script directory, I needed to create a cross-
reference chart
that shows what script depends on what other script.
My Perl script (below) works in terms of doing what I need, however,
IMO, it appears to run a bit slow. I timed it at ~3.5 sec. Possibly
that is it's max performance but something tells me (from other Perl
script experiences) this one just isn't up to speed.
I would appreciate any ideas or comments.
Thanks, Jorge
#!/usr/bin/perl -l
use strict;
use warnings;
&scripts_dir('/some/dir/that/holds/scripts');
sub scripts_dir {
# set some vars
my $dir = shift;
my(@paths, $paths, @scripts, $scripts, $string);
my($lines, $leaf, $header, $header2);
local($_);
# check dir can be opened for read
unless (opendir(DIR, $dir)) {
die "can't open $dir $!\n";
closedir(DIR);
return;
}
#
# read dir, skip over system files and bak files
# build array of script names
# build array of full-path script names
#
foreach (readdir(DIR)) {
next if $_ eq '.' || $_ eq '..' || $_ =~ /\.bak$/;
push(@scripts, $_);
$paths = $dir."/".$_;
push(@paths, $paths);
}
closedir(DIR);
# open ouput file, format and print headers
open OUT, ">output" or die "cannot open output for writing $! ...
\n";
$header = sprintf("%-25s%-25s%s", "SCRIPT NAME", "FOUND IN",
"USAGE");
$header2 = sprintf("%-25s%-25s%s", "===========", "========",
"=====");
print OUT $header;
print OUT $header2;
# loop through each script name
foreach $scripts(@scripts){
# loop through each script in directory
foreach my $paths(@paths){
# get last leaf of script being searched --
# if it matches itself; skip
$leaf = get_leaf($paths);
if($scripts eq $leaf) { next;}
# open each script for searching
open F, "$paths" or die "cannot open $paths for reading
$! ...\n";
while(my $lines = <F>) {
# -l switch in place
chomp($lines);
# search for matches to the commonly-used command
syntax
if($lines =~ /\$\($scripts / || $lines =~ /\`
$scripts /){
# format to line up with headers
$string = sprintf("%-25s%-25s%s", $scripts, $leaf,
$lines);
# print to file
print OUT $string;
}
}
}
}
# close I/O streams
close(F);
close(OUT);
}
#======================
# subroutine get_leaf
#======================
sub get_leaf
{
# get arg(s)
my($pathname) = @_;
# split on leafs
my @split_pathname = split( /[\\\/]/, $pathname);
# grab last leaf
my $leaf = pop( @split_pathname );
# return bare script name (leaf)
return( $leaf );
}
__END__