error handling - ¿Puede awk omitir archivos que no existen, sin carreras?
error-handling race-condition (6)
¿Hay alguna manera de hacer que awk (gawk) ignore u omita archivos perdidos? Es decir, archivos pasados en la línea de comandos que ya no existen en el sistema de archivos (por ejemplo, archivos que aparecen / desaparecen rápidamente en / proc / [1-9] *).
Por defecto, un archivo faltante es un error fatal :-(
Me gustaría poder hacer el equivalente a algo como esto:
BEGIN { MISSING_FILES_ARE_FATAL = 0 } # <- Wishful thinking!
{ count++ }
END { print count }
Un script de envoltura no puede verificar que los archivos existan antes de que se ejecute awk, ya que pueden desaparecer entre el momento en que se comprueban y awk y luego intenta abrirlos, es decir, es una condición de carrera. (También es una condición de carrera verificar-y-luego-abrir dentro de awk, aunque el tiempo es más estricto)
Bueno, puede consultar con el sistema de llamada en los contenidos de ARGV
, luego procesarlos a través de getline
.
if (system("test -r " ARGV[1]) == 0)
while ( (getline aline < ARGV[1]) >0 )
# process ARGV[1] via `aline` instead of $0
...
Luego procese ARGV [2], etc. HTH
En la mejor de las tradiciones, responderé a su pregunta con un programa Perl.
#!/usr/bin/perl -w
for my $file (@ARGV) {
open my $fh, $file or next;
while(<$fh>) {
...do your thing here...
}
}
(No es extraño, pero es la única solución sin una condición de carrera).
Incluso pegando un perl o shell wrapper alrededor de su script awk, creo que todavía habrá una condición de carrera. Por ejemplo, usando el fragmento de shell de ADEpt por lo demás fino:
[ -r "$filename" ] && awk -f ... $filename
no hay nada que impida que el proceso se salga entre el -r y el tiempo en que awk intenta abrir el archivo ...
La única respuesta que se me ocurre es usar LD_PRELOAD para reemplazar la llamada abierta del sistema por awk, de modo que si falta el archivo, se abre un descriptor de archivo de lectura en / dev / null.
Aquello podría funcionar...
Oh, lo siento. Ignora mi respuesta anterior. Aquí hay otra sugerencia:
cat /proc/[1-9]* 2>/dev/null | awk ....
Cat se tragará todos los archivos, faltan y existen por igual, el error de gato se abandonará al olvido (el archivo faltante es un error no fatal para cat), y el awk podrá procesar el resultado.
Me parece que una característica "MISSING_FILES_ARE_FATAL = 0" será parte de la próxima versión de gawk. Vea el archivo ChangeLog del actual código fuente estable de gawk:
--- snip ---
Vie 22 Ago 14:43:49 2008 Arnold D. Robbins
* io.c (nextfile): Users Strong In The Ways Of The Source can use
non-existant files on the command line without it being a fatal error.
--- snip ---
http://cvs.savannah.gnu.org/viewvc/gawk-stable/ChangeLog?revision=1.87&root=gawk&view=markup
Hermann
GAWK 4 tiene BEGINFILE
en el que puede probar ERRNO
y hacer un siguiente nextfile
si ERRNO
no está vacío (lo que indica que el archivo no se pudo abrir).