Временно перенаправить STDOUT в / dev / null - не работает все время - PullRequest
4 голосов
/ 28 июня 2009

Я использую

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

При ссылке на STDIN, STDOUT и 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.

Я понимаю, что это не работает все время. Например, я обновляю страницу 10 раз. Х раз он распечатает «X BEGIN HELLO WORLD». (10-х) раз он просто ничего не распечатывает.

Я не могу найти причину, по которой он так себя ведет. Могу ли я узнать, что кто-нибудь из вас сталкивался с подобной проблемой, как я?

Ответы [ 4 ]

5 голосов
/ 30 июня 2009

Мне нужно явно хранить и восстанавливать. Это работает для моего случая. Но я не уверен, почему.

# 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: $!";
2 голосов
/ 28 июня 2009

Попробуйте:

local $|=1;

до print. Это обход буферизации.

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

1 голос
/ 29 июня 2009

Буферизация - наиболее вероятная проблема, как уже отмечалось, но есть другой подход, если он не работает для вас по какой-либо причине. Вы можете использовать встроенную функцию org-ignore one-arg select (), чтобы изменить дескриптор файла вывода по умолчанию для вывода на печать.

1 голос
/ 28 июня 2009

Могу поспорить, что это взаимодействие mod_perl и переназначение глобуса STDOUT - вы эффективно запускаете один экземпляр perl на веб-сервере, тогда это приведет к состоянию гонки при выходе из режима local области действия, и когда происходят различные print и close.

Это в основном мое предположение, я не знаю точно, что это происходит, так что имейте это в виду. Грубо говоря, условие гонки будет между, когда вы сделаете это:

local *STDOUT = $nullfh;

и когда это local выходит из области видимости. Я думаю, что запросы к веб-серверу обрабатываются как разные потоки (поскольку мы используем mod_perl), и каждый поток может увидеть новое значение для глобуса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...