¿Por qué Perl no imprime el último texto antes de salir?
Pregunta
Mi código no ejecutará la última línea justo antes de " exit;
" y no tengo idea de por qué. Traté de poner una línea printf $ fh
adicional antes de exit
, pero tampoco funcionó; no imprimiría ninguna línea. Todo lo demás se imprime bien, excepto las últimas declaraciones de impresión antes de la salida.
¿Alguna pista de por qué sucede esto? O mejor aún, ¿cómo solucionarlo o solucionarlo?
if($i>0 && $i<3)
{
printf $fh "Partial match found.\n";
if($matched_uid){printf $fh "UID #: ".$arguid." exists.\n";}
if($matched_id){printf $fh "ID #: ".$argid." exists.\n";}
if($matched_uname){printf $fh "Username: ".$arguname." exists.\n";}
printf $fh "Aborting.";
exit;
}
EDITAR:
Parte del código que copié contenía esto
select $fh; $| = 1; #set auto flush
Quizás es por eso que mis resultados no se pudieron duplicar ...
Solución
Pruebe " Abortar. \ n "
Esto parece un problema de almacenamiento en búfer.
Otros consejos
Di R. Bemrose mi voto, pero si $ fh es un MANEJO DE ARCHIVO es posible que también desee cerrar
antes de finalizar.
Además, está utilizando printf
incorrectamente. printf es no 'imprimir archivo'. su 'formato de impresión'.
Para ese último ejemplo
print $fh 'Message' ;
Es todo lo que necesitas.
printf
está destinado a ser utilizado así:
printf $fh 'some format %s and more %s ' , $var , $var ;
o
printf 'some format %s and more %s ' , $var , $var ;
y su equivalente a hacer
print $fh sprintf 'format %s more %s' , $var , $var ;
Y debido a esto, está poniendo riesgos de código innecesarios en caso de que cualquiera de sus variables concatenadas se expanda para tener '%' en ellas. Para ver un ejemplo de personas que caen en esta trampa, consulte Q : 308417: ¿Por qué mi script Perl elimina caracteres del archivo?
perldoc -f print
print FILEHANDLE LIST print LIST print Prints a string or a list of strings.
perldoc -f printf
printf FILEHANDLE FORMAT, LIST printf FORMAT, LIST Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\" (the output record separator) is not appended
Sondeo adicional
He estado investigando tu problema aún más porque no puedo obtener tu "almacenamiento en búfer" condición para que ocurra. Todos mis archivos se vacían correctamente, ya sea que los vacíe o no. (Perl 5.10).
Aquí está mi fragmento de código que estoy intentando:
#!/usr/bin/perl
use strict;
use warnings;
open my $fh , '>' , '/tmp/oo.txt';
my $exit_at = int(rand( 200_000 ));
print "$exit_at\n";
sleep 2;
for ( 0 .. ( $exit_at * 2 ) ){
print $fh Di R. Bemrose mi voto, pero si $ fh es un MANEJO DE ARCHIVO es posible que también desee cerrar
antes de finalizar.
Además, está utilizando printf
incorrectamente. printf es no 'imprimir archivo'. su 'formato de impresión'.
Para ese último ejemplo
print $fh 'Message' ;
Es todo lo que necesitas.
printf
está destinado a ser utilizado así:
printf $fh 'some format %s and more %s ' , $var , $var ;
o
printf 'some format %s and more %s ' , $var , $var ;
y su equivalente a hacer
print $fh sprintf 'format %s more %s' , $var , $var ;
Y debido a esto, está poniendo riesgos de código innecesarios en caso de que cualquiera de sus variables concatenadas se expanda para tener '%' en ellas. Para ver un ejemplo de personas que caen en esta trampa, consulte Q : 308417: ¿Por qué mi script Perl elimina caracteres del archivo?
perldoc -f print
print FILEHANDLE LIST
print LIST
print Prints a string or a list of strings.
perldoc -f printf
printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\"
(the output record separator) is not appended
Sondeo adicional
He estado investigando tu problema aún más porque no puedo obtener tu "almacenamiento en búfer" condición para que ocurra. Todos mis archivos se vacían correctamente, ya sea que los vacíe o no. (Perl 5.10).
Aquí está mi fragmento de código que estoy intentando:
Modification of a read-only value attempted at iotest.pl line 15.
Estoy usando tu mal uso de printf.
La línea que se comenta expulsa un mensaje de error, porque no es válida debido a que nadie proporciona el parámetro 'n', y muere con:
<*>
Antes de ejecutar la impresión de 'última línea' (también está mal, pero no hay símbolos de% en ella, así que está bien) haciendo que la 'última línea' esté ausente del archivo de salida.
Arregle su printf y use la impresión simple y antigua en su lugar y vea si eso resuelve su problema.
;
if ( Di R. Bemrose mi voto, pero si $ fh es un MANEJO DE ARCHIVO es posible que también desee cerrar
antes de finalizar.
Además, está utilizando printf
incorrectamente. printf es no 'imprimir archivo'. su 'formato de impresión'.
Para ese último ejemplo
print $fh 'Message' ;
Es todo lo que necesitas.
printf
está destinado a ser utilizado así:
printf $fh 'some format %s and more %s ' , $var , $var ;
o
printf 'some format %s and more %s ' , $var , $var ;
y su equivalente a hacer
print $fh sprintf 'format %s more %s' , $var , $var ;
Y debido a esto, está poniendo riesgos de código innecesarios en caso de que cualquiera de sus variables concatenadas se expanda para tener '%' en ellas. Para ver un ejemplo de personas que caen en esta trampa, consulte Q : 308417: ¿Por qué mi script Perl elimina caracteres del archivo?
perldoc -f print
print FILEHANDLE LIST
print LIST
print Prints a string or a list of strings.
perldoc -f printf
printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\"
(the output record separator) is not appended
Sondeo adicional
He estado investigando tu problema aún más porque no puedo obtener tu "almacenamiento en búfer" condición para que ocurra. Todos mis archivos se vacían correctamente, ya sea que los vacíe o no. (Perl 5.10).
Aquí está mi fragmento de código que estoy intentando:
<*>
Estoy usando tu mal uso de printf.
La línea que se comenta expulsa un mensaje de error, porque no es válida debido a que nadie proporciona el parámetro 'n', y muere con:
<*>
Antes de ejecutar la impresión de 'última línea' (también está mal, pero no hay símbolos de% en ella, así que está bien) haciendo que la 'última línea' esté ausente del archivo de salida.
Arregle su printf y use la impresión simple y antigua en su lugar y vea si eso resuelve su problema.
== $exit_at ){
printf $fh '%n' ; # Bad Code Causes Early Death.
printf $fh 'last line';
exit;
}
if ( Di R. Bemrose mi voto, pero si $ fh es un MANEJO DE ARCHIVO es posible que también desee cerrar
antes de finalizar.
Además, está utilizando printf
incorrectamente. printf es no 'imprimir archivo'. su 'formato de impresión'.
Para ese último ejemplo
print $fh 'Message' ;
Es todo lo que necesitas.
printf
está destinado a ser utilizado así:
printf $fh 'some format %s and more %s ' , $var , $var ;
o
printf 'some format %s and more %s ' , $var , $var ;
y su equivalente a hacer
print $fh sprintf 'format %s more %s' , $var , $var ;
Y debido a esto, está poniendo riesgos de código innecesarios en caso de que cualquiera de sus variables concatenadas se expanda para tener '%' en ellas. Para ver un ejemplo de personas que caen en esta trampa, consulte Q : 308417: ¿Por qué mi script Perl elimina caracteres del archivo?
perldoc -f print
print FILEHANDLE LIST
print LIST
print Prints a string or a list of strings.
perldoc -f printf
printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\"
(the output record separator) is not appended
Sondeo adicional
He estado investigando tu problema aún más porque no puedo obtener tu "almacenamiento en búfer" condición para que ocurra. Todos mis archivos se vacían correctamente, ya sea que los vacíe o no. (Perl 5.10).
Aquí está mi fragmento de código que estoy intentando:
<*>
Estoy usando tu mal uso de printf.
La línea que se comenta expulsa un mensaje de error, porque no es válida debido a que nadie proporciona el parámetro 'n', y muere con:
<*>
Antes de ejecutar la impresión de 'última línea' (también está mal, pero no hay símbolos de% en ella, así que está bien) haciendo que la 'última línea' esté ausente del archivo de salida.
Arregle su printf y use la impresión simple y antigua en su lugar y vea si eso resuelve su problema.
% 1000 ){
print $fh "\n";
}
}
Estoy usando tu mal uso de printf. La línea que se comenta expulsa un mensaje de error, porque no es válida debido a que nadie proporciona el parámetro 'n', y muere con:
<*>Antes de ejecutar la impresión de 'última línea' (también está mal, pero no hay símbolos de% en ella, así que está bien) haciendo que la 'última línea' esté ausente del archivo de salida.
Arregle su printf y use la impresión simple y antigua en su lugar y vea si eso resuelve su problema.
Perl amortigua su salida. Puede desactivar el almacenamiento en búfer automático con
local $| = 1;
Editar: ¡De alguna manera golpeé! en lugar de | la primera vez ... arreglado. No tengo idea de cómo sucedió eso, están en lados opuestos del teclado.
Sobre el tema del uso apropiado de print
, te haces las cosas un poco difíciles.
Interpola tus variables en lugar de concatenar las cadenas juntas. Utilice una declaración de impresión con una lista de cadenas para imprimir, en lugar de varias cadenas.
Aquí hay una manera:
if( $i>0 && $i<3 )
{
print $fh join "\n",
"Partial match found.",
$matched_uid ? "UID #: $arguid exists." : (),
$matched_id ? "ID #: $argid exists." : (),
$matched_uname ? "Username: $arguname exists." : (),
"Aborting.",
;
exit;
}
El ()
en el lado falso del operador ternario es una lista vacía, que desaparecerá cuando los argumentos a unir se aplanen. Si hubiera usado una cadena vacía ( ''
), cada criterio no coincidente habría producido una línea en blanco adicional en los resultados.
También puede agregar su propia línea nueva en cada elemento y luego omitir la combinación, si cree que es más legible:
print $fh
"Partial match found.\n",
$matched_uid ? "UID #: $arguid exists.\n" : '',
...
Debe agregar un \ n final a la última impresión. De lo contrario, la salida no se enjuaga a la consola.
O David Norman tiene razón, o el problema está en otro lugar. Acabo de escribir el código dentro del bloque if en el intérprete perl, e imprimió "Aborting". como se esperaba. (Funcionó para mí incluso sin el carácter de nueva línea que termina).