Perl:将 STDERR 重定向到文件而不创建空文件?
我在 perl 脚本中重定向 STDOUT 和 STDERR ,方法是:
open STDOUT, '>', $logfile or die "Can't redirect STDOUT: $!";
open STDERR, ">&STDOUT" or die "Can't dup for STDERR: $!";
保存和恢复之前和之后的文件句柄...
事情是,如果程序没有输出,我最终会得到一个大小为 0 的文件,但我希望有根本没有文件。如何在不手动检查和删除文件的情况下做到这一点?
谢谢!
I'm redirecting STDOUT and STDERR in a perl script with:
open STDOUT, '>', $logfile or die "Can't redirect STDOUT: $!";
open STDERR, ">&STDOUT" or die "Can't dup for STDERR: $!";
saving and restoring the file handles before and after ...
Thing is, if there's no output from the program I end up with a size 0 file but I'd like to have no file at all. How can I do that without resorting to checking and deleting the file manually?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以将 STDOUT 绑定到一个延迟打开目标文件的类,直到第一次写入句柄为止:
然后在主程序中,您会说:
要恢复以前的句柄,您会说:
You could tie STDOUT to a class that delays opening of the destination file until the first time the handle is written to:
Then in your main program, you'd say:
To restore the previous handles you'd say:
只需检查最后是否写入了任何内容,如果没有,则删除该文件。确保您已打开自动冲洗功能。
或者是旧式的...
Just check at the end if anything has been written, and if not, remove the file. Make sure you have autoflush on.
Or in the old style...
我能想到的唯一方法是分叉一个子进程,该子进程通过管道发送回所有内容(想想 IO::Pipe 或类似 IPC::Open2 的东西 - 无论哪种方式,你仍然将 STDERR 重定向到子进程中的 STDOUT),然后在父级中,将管道中获得的内容写入日志文件 - 这允许您在第一次获得数据时打开日志文件。例如:
当我运行这个时,我得到:
希望有帮助。
The only way I can think of is to fork off a subprocess which sends back everything via pipe (think IO::Pipe or something like IPC::Open2 - either way, you still redirect your STDERR to STDOUT in the child), and then in the parent, write the stuff you get in the pipe to the log file - this allows you to open the logfile when you first have data. For example:
When I run this, I get:
Hope that helps.
您不想延迟打开文件,如果确实延迟打开,任何问题(例如权限错误或文件路径中缺少目录)都会导致程序在第一个打印语句处失败。鉴于听起来您的程序运行可能永远不会打印任何内容,您可能会在未来的某个随机时间面临程序失败,因为它恰好打印到几个月内无法打开的文件。到那时,您或您的继任者可能已经忘记了此功能的存在。
最好在完成后检查该文件,看看它是否为空,如果是则将其删除。
如果您想为您执行此操作,可以将逻辑包装在一个类中。
此代码并未真正准备好用于生产,它不会尝试处理可以调用
IO::File->new()
的所有方式,并且它还应该覆盖对的调用$file_obj->open()
的方式与new
类似。它还可以提供更好的错误处理。You don't want to delay opening the file, if you do delay the open any problems like a permission error, or a missing directory in the path to the file will cause the program to fail at the first print statement. Given that it sounds like you might have program runs that never print anything you could likely face your program failing at some random time in the future because it just happened to print to a file that it couldn't open for months. By then you, or your successor might have forgotten this feature ever existed.
It's much better to check the file after your done to see if it's empty and remove it if it is.
You can wrap the logic in a class if you want to do it for you.
This code isn't really production ready, it doesn't try to handle all the ways
IO::File->new()
can be called, and it should also override calls to$file_obj->open()
in a similar manner tonew
. It also could do with better error handling.