暂时将 STDOUT 重定向到 /dev/null - 始终不工作

发布于 2024-07-25 11:08:16 字数 889 浏览 10 评论 0原文

我正在使用

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 次它会打印出“X BEGIN HELLO WORLD”。 (10-x) 次它什么也没打印出来。

我找不到它这样做的任何原因。 我可以知道你们中有人遇到和我类似的问题吗?

I am using

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

By refering to STDIN, STDOUT, and 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.

I realize that it is not working all the time. For example, I refresh the page for 10 times. x times it will print out "X BEGIN HELLO WORLD". (10-x) time it just print out nothing.

I cannot find any reason why it behave this way. May I know anyone of you encounter similar problem as me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅浅 2024-08-01 11:08:16

我需要显式存储和恢复。 它适用于我的情况。 但我不知道为什么。

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

I need to explicitly store and restore. It works for my case. But I am not sure why.

# 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: $!";
余生一个溪 2024-08-01 11:08:16

尝试:

local $|=1;

打印之前。 这绕过了缓冲。

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

Try:

local $|=1;

before print. This bypass the buffering.

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

眼泪淡了忧伤 2024-08-01 11:08:16

正如已经提到的,缓冲是最有可能出现的问题,但是如果由于某种原因这对您不起作用,还有另一种方法。 您可以使用经常被忽略的内置 one-arg select() 来更改打印输出的默认输出文件句柄。

Buffering is the most likely problem, as noted already, but there's another approach if that doesn't work for you for whatever reason. You can use the oft-ignored one-arg select() built-in to change the default output filehandle for print output.

甜嗑 2024-08-01 11:08:16

我敢打赌这是 mod_perl 的交互,以及 STDOUT glob 的重新分配 - 您实际上是在网络服务器中运行一个 perl 实例,那么这将导致 local 超出范围,以及当各种 printclose 发生时。

这基本上是我的猜测,我不确定它是否正在发生,所以请记住这一点。 粗略地说,竞争条件将发生在您执行此操作时:

local *STDOUT = $nullfh;

和此 local 超出范围之间。 我认为对 Web 服务器的请求是作为不同的线程处理的(因为我们使用的是 mod_perl),并且每个线程都可以看到 glob 的新值。

I bet it is an interaction of mod_perl, and the reassignment of the STDOUT glob - you are effectively running one instance of perl in the webserver, then this will lead to a race condition on when the local goes out of scope, and when the various print's and close's happen.

This is basically a guess of mine, I don't know for sure that it is happening so keep that in mind. Roughly speaking the race condition would be between when you do this:

local *STDOUT = $nullfh;

and when this local goes out of scope. I think that requests to the web server are handled as different threads (since we are using mod_perl), and each thread may be able to see the new value for the glob.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文