如何重新初始化 Perl 的 STDIN/STDOUT/STDERR?

发布于 2024-08-03 05:00:22 字数 684 浏览 5 评论 0原文

我有一个 Perl 脚本,它可以自行分叉和守护进程。它是由 cron 运行的,所以为了不留下僵尸,我关闭了 STDIN、STDOUT 和 STDERR:

open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
if (!fork()) {
  do_some_fork_stuff();
  }

我的问题是:我想在此之后至少恢复 STDOUT(最好恢复其他2)。但是我需要使用什么魔法符号才能像以前那样重新打开 STDOUT?

我知道如果我从 tty 运行,我可以使用“/dev/tty”(但我是从 cron 运行并依赖于其他地方的 stdout)。我还读过一些技巧,您可以使用 open SAVEOUT,">&STDOUT" 将 STDOUT 放在一边,但仅制作此副本的行为并不能解决留下僵尸的原始问题大约。

我想看看是否有像 open STDOUT,"|-" (我知道不是)这样的魔法以应有的方式打开 STDOUT。

I have a Perl script which forks and daemonizes itself. It's run by cron, so in order to not leave a zombie around, I shut down STDIN,STDOUT, and STDERR:

open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
if (!fork()) {
  do_some_fork_stuff();
  }

The question I have is: I'd like to restore at least STDOUT after this point (it would be nice to restore the other 2). But what magic symbols do I need to use to re-open STDOUT as what STDOUT used to be?

I know that I could use "/dev/tty" if I was running from a tty (but I'm running from cron and depending on stdout elsewhere). I've also read tricks where you can put STDOUT aside with open SAVEOUT,">&STDOUT", but just the act of making this copy doesn't solve the original problem of leaving a zombie around.

I'm looking to see if there's some magic like open STDOUT,"|-" (which I know isn't it) to open STDOUT the way it's supposed to be opened.

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

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

发布评论

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

评论(3

月亮邮递员 2024-08-10 05:00:22

# 文件描述符的副本

open(CPERR, ">&STDERR");

# 将 stderr 重定向到警告文件

open(STDERR, ">>xyz.log") || die "Error stderr: $!";

# 关闭重定向的文件句柄

close(STDERR) || die "Can't close STDERR: $!";

# 恢复 stdout 和 stderr

open(STDERR, ">&CPERR") || die "Can't restore stderr: $!";

# 我希望这对您有用。

#-哈里普拉萨德 AJ

# copy of the file descriptors

open(CPERR, ">&STDERR");

# redirect stderr in to warning file

open(STDERR, ">>xyz.log") || die "Error stderr: $!";

# close the redirected filehandles

close(STDERR) || die "Can't close STDERR: $!";

# restore stdout and stderr

open(STDERR, ">&CPERR") || die "Can't restore stderr: $!";

#I hope this works for you.

#-Hariprasad AJ

霓裳挽歌倾城醉 2024-08-10 05:00:22

如果它仍然有用,我会想到两件事:

  1. 您可以仅在子进程中关闭 STDOUT/STDERR/STDIN(即 if (!fork())。这将允许父进程仍然使用它们,因为它们'仍然会在那里打开。

  2. 我认为您可以使用更简单的 close(STDOUT) 而不是将其打开到 /dev/null。

例如:

if (!fork()) {
    close(STDIN) or die "Can't close STDIN: $!\n";
    close(STDOUT) or die "Can't close STDOUT: $!\n";
    close(STDERR) or die "Can't close STDERR: $!\n";
    do_some_fork_stuff();
}

If it's still useful, two things come to mind:

  1. You can close STDOUT/STDERR/STDIN in just the child process (i.e. if (!fork()). This will allow the parent to still use them, because they'll still be open there.

  2. I think you can use the simpler close(STDOUT) instead of opening it to /dev/null.

For example:

if (!fork()) {
    close(STDIN) or die "Can't close STDIN: $!\n";
    close(STDOUT) or die "Can't close STDOUT: $!\n";
    close(STDERR) or die "Can't close STDERR: $!\n";
    do_some_fork_stuff();
}
零度℉ 2024-08-10 05:00:22

一旦关闭,就没有办法恢复了。

为什么又需要STDOUT?将消息写入控制台?为此,请使用 /dev/console,或使用 Sys::Syslog 写入系统日志。

老实说,另一个答案是正确的。如果您想稍后重新打开它,则必须保存旧的标准输出(克隆到新的 fd)。它确实解决了“僵尸”问题,因为您可以将 fd 0(以及 1 和 2)重定向到 /dev/null。

Once closed, there's no way to get it back.

Why do you need STDOUT again? To write messages to the console? Use /dev/console for that, or write to syslog with Sys::Syslog.

Honestly though, the other answer is correct. You must save the old stdout (cloned to a new fd) if you want to reopen it later. It does solve the "zombie" problem, since you can then redirect fd 0 (and 1 & 2) to /dev/null.

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