Domanda

Sto usando

Server version: Apache/1.3.34 (Debian)
mod_perl - 1.29

Riferendosi a STDIN, STDOUT, e STDERR Streams

#!/usr/bin/perl5
package main;

use strict 'vars';

{
    # Our mighty holy legacy code love to print out message in the middle of operation. Shihh....
    # Let's quietly redirect those message to /dev/null.
    my $nullfh = Apache::gensym( );
    open $nullfh, '>/dev/null' or warn "Can't open /dev/null: $!";
    local *STDOUT = $nullfh;
    print "BYE BYE WORLD";    # Shouldn't show in webpage.
    close $nullfh;
}

print "X BEGIN HELLO WORLD";  # Should show in webpage.

Mi rendo conto che non funziona sempre. Ad esempio, aggiorno la pagina per 10 volte. x volte verrà stampato " X INIZIA CIAO MONDO " ;. (10-x) volta che non stampa nulla.

Non riesco a trovare alcun motivo per cui si comporti in questo modo. Posso sapere che qualcuno di voi ha problemi simili a me?

È stato utile?

Soluzione

Devo archiviare e ripristinare esplicitamente. Funziona per il mio caso. Ma non sono sicuro del perché.

# Take copies of the file descriptors
open OLDOUT, '>&STDOUT';
my $returned_values = 0;
{
    # Our mighty holy legacy code love to print out message in the middle of operation. Shihh....
    # Let's quietly redirect those message to /dev/null.
    local *STDOUT;
    open STDOUT, '>/dev/null' or warn "Can't open /dev/null: $!";
    print "BYE BYE WORLD";    # Shouldn't show in webpage.
    close STDOUT;
}
# Restore stdout.
open STDOUT, '>&OLDOUT' or die "Can't restore stdout: $!";
# Avoid leaks by closing the independent copies.
close OLDOUT or die "Can't close OLDOUT: $!";

Altri suggerimenti

Prova:

local $|=1;

prima di print. Questo aggira il buffering.

Vedi http://perldoc.perl.org/perlvar .html # HANDLE-% 3Eautoflush% 28EXPR% 29

Il buffering è il problema più probabile, come già notato, ma c'è un altro approccio se questo non funziona per qualsiasi motivo. È possibile utilizzare il one-arg ignorato spesso () incorporato per modificare il filehandle di output predefinito per l'output di stampa.

Scommetto che è un'interazione di mod_perl e la riassegnazione del STDOUT glob - stai effettivamente eseguendo un'istanza di perl nel server web, quindi questo porterà a una condizione di competizione quando local si spegne di ambito e quando si verificano i vari print e close.

Questa è fondamentalmente una mia ipotesi, non so per certo che sta succedendo, quindi tienilo a mente. In parole povere le condizioni di gara sarebbero tra quando fai questo:

local *STDOUT = $nullfh;

e quando questo <=> non rientra nell'ambito. Penso che le richieste al web server siano gestite come thread diversi (poiché stiamo usando mod_perl) e ogni thread potrebbe essere in grado di vedere il nuovo valore per il glob.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top