Временно перенаправить стандартный вывод в /dev/ null - Работает не все время

StackOverflow https://stackoverflow.com/questions/1054579

  •  20-08-2019
  •  | 
  •  

Вопрос

Я использую

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

Ссылаясь на Потоки STDIN, STDOUT и STDERR

#!/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 раз он напечатает "X BEGIN ПРИВЕТ, МИР".(10-x) раз, когда он просто ничего не распечатывает.

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

Это было полезно?

Решение

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

# 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: $!";

Другие советы

Попробуй:

local $|=1;

до того , как print.Это позволяет обойти буферизацию.

Видишь http://perldoc.perl.org/perlvar.html#HANDLE-%3Eautoflush%28EXPR%29

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

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

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

local *STDOUT = $nullfh;

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top