Hola a todos. Estoy intentando crear un archivo
.log bastante simple para un pequeño
script y me asaltaron algunas dudas sobre cómo hacerlo de manera correcta y sin módulos extra (solo los que trae la distribución básica).
El código que poseo es el siguiente:
Using perl Syntax Highlighting
#!/usr/bin/env perl
use v5.26;
use Getopt::Long qw(:config bundling_values require_order no_ignore_case);
use FileHandle;
use File::Copy;
use POSIX qw(strftime);
use File::Temp qw(tempdir);
use Cwd;
use autodie;
my $verbose = 0; # verbose
my $debug; # debug
my $result = GetOptions (
'debug!' => \$debug, # debug
'verbose!' => \$verbose, # verbose
) or die "No es una opción valida\n";
### Mensajes de error extendidos
sub exterr () {
chomp(my $msg_errno = $!);
chomp(my $msg_extended_os_error = $^E);
if ($msg_errno eq $msg_extended_os_error) {
$msg_errno;
}
else {
"$msg_errno/$msg_extended_os_error";
}
}
### Nombre del script
chomp(my $scriptname = `basename $0`);
$scriptname =~ s/\.pl$//;
### Directorios y archivos
my $tempDir = tempdir( CLEANUP => 1);
my $workdir = cwd;
my $LogFileName = "$tempDir/$scriptname.log";
my $Log_file = new FileHandle;
my $StampTime = strftime ("%y/%m/%d %H:%M:%S", localtime);
### Abrimos
$Log_file->open("> $LogFileName");
$Log_file->print("[$StampTime] * Se inicio $scriptname en $workdir\n");
$Log_file->print("[$StampTime] * Se creo el directorio $tempDir\n");
$Log_file->print("[$StampTime] * Se creo el archivo $tempDir/$scriptname.log\n");
### Log simple
sub Log {
my $msg = shift;
my $now = strftime ("%y/%m/%d %H:%M:%S", localtime);
$Log_file->print(sprintf "[%s] %s\n", $now, $msg);
print "$msg\n" if $verbose;
return 0
}
### Captura y ejecución de comandos
sub RUNOSCMD {
my $cmdname = shift;
my $argcmd = shift;
my $captured = $cmdname." ".$argcmd;
Log("* Runing: $captured");
$captured = qx{$captured};
if ($? == -1) {
$cmdname = "* Error!!: ".$cmdname." failed to execute (%s)!\n";
$Log_file->print(sprintf "$cmdname", exterr);
die sprintf "$cmdname", exterr;
} elsif ($? & 127) {
$cmdname = "* Error!!: ".$cmdname." died with signal %d!\n";
$Log_file->print(sprintf "$cmdname", ($? & 127));
die sprintf "$cmdname", ($? & 127);
} elsif ($? != 0 ) {
$cmdname = "* Error!!: ".$cmdname." exited with error code %d!\n";
$Log_file->print(sprintf "$cmdname", $? >> 8);
die sprintf "$cmdname",$? >> 8;
} else {
$Log_file->print($captured);
print($captured) if $verbose;
}
}
### Agregamos algunas líneas a nuestro log
Log("Una línea agregada al log");
Log("Otra línea agregada al log");
### Definimos un comando
my $cmd = "ls";
say "Ejecutando $cmd";
RUNOSCMD($cmd, "-lh");
Log("Otra línea agregada al log");
### Definimos otro comando (no existente)
my $newwcmd = "XX";
say "Ejecutando $newwcmd";
RUNOSCMD($newwcmd, "-lh");
Log("Esta línea no se agrega porque XX a dado un error");
END {
$Log_file->print("[$StampTime] * Se cierra el archivo $LogFileName");
close $Log_file;
### Movemos el archivo al directorio de trabajo
if ($debug) {
move("$tempDir/$scriptname.log", "$workdir/$scriptname.log")
or die "* Error!!: No puedo mover $scriptname.log";
}
say "Sayonara";
}
__END__
Coloreado en 0.007 segundos, usando
GeSHi 1.0.8.4
En él he definido dos funciones
Log que sólo agrega líneas al archivo
.log y
RUNOSCMD que se encarga de ejecutar un comando de sistema capturando la salida y analizando los valores.
Al ejecutar el
script con las opciones correctas todo parece ir bien, pero, si se pasa una opción desconocida,
--k, por ejemplo, se obtiene:
Using text Syntax Highlighting
Unknown option: k
No es una opción valida
Can't call method "print" on an undefined value at mylog.pl line 103.
END failed--call queue aborted.
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
Y aquí es donde empieza mi problema. Las líneas:
Using text Syntax Highlighting
Can't call method "print" on an undefined value at mylog.pl line 103.
END failed--call queue aborted.
Coloreado en 0.000 segundos, usando
GeSHi 1.0.8.4
no deberían aparecer, al pasar
--k el
script debería salir, asumo que es por el uso de
END {, pero, si muevo el código de lugar, uso la opción
--debug y ocurre algún error, no obtengo el archivo
.log en el directorio de trabajo.
¿Existe una forma mejor de lograr esto?
Saludos.