我正在编写一个Perl脚本,它将为我们的应用程序安装软件更改。这主要涉及在sqlplus中运行sql文件。虽然我记录每个运行的sql文件并grep每个日志文件以查找错误,但我希望获得所有内容的单个日志文件。这样,如果在安装过程中出现奇怪的事情,我将会有一个文件,其中包含安装补丁时发生的所有事情。如果我用bash写这个,我会做以下事情:
exec >my_log_file
exec 2>&1
... some code runs
exec 1>&-
exec 2>&-
exec命令会将转到stdout和stderr的任何内容重定向到我的日志文件。在脚本结束时,我将其关闭,以便我可以在日志中查找错误。我还可以将stdout重定向回/ dev / tty并根据需要记录日志。
是否有纯粹的Perl方式来获得相同的效果?我猜测如果我在Perl中使用system命令运行上面的代码,我正在创建一个新进程,因此无法获得脚本的所有输出。我还考虑过为日志记录创建一个bash包装器脚本,但这需要客户运行包装器脚本。如果我能在Perl中做到这一点会更容易。
感谢。
答案 0 :(得分:2)
以下内容大致改编自" perldoc -f open"中的示例。
# Take copies of the original STDOUT and STDERR.
open(my $oldout, ">&", \*STDOUT) or die "Can't dup STDOUT: $!";
open(my $olderr ">&", \*STDERR) or die "Can't dup STDERR: $!";
# Open STDOUT to a log file
open(STDOUT, '>', 'my_file.log') or die "Can't redirect STDOUT: $!";
# Copy STDERR to STDOUT
open(STDERR, ">&STDOUT") or die "Can't dup STDOUT: $!";
# Unbuffer STDOUT and STDERR
select STDERR; $| = 1;
select STDOUT; $| = 1;
# Do stuff that prints to STDOUT and STDERR
...
# Restore original STDOUT and STDERR
open(STDOUT, ">&", $oldout) or die "Can't dup \$oldout: $!";
open(STDERR, ">&", $olderr) or die "Can't dup OLDERR: $!";