将标准输出与标准错误重定向至文件的子程序及Perl示例咨询
Got it, let's break this down into two practical approaches for redirecting stdout and stderr to files—one that doesn't require changing your Perl code, and another that lets you handle it programmatically within simplecalc.pl. Here's what you need to know:
If you just need to capture output when running the script, shell redirection is the quickest way. Use these commands depending on your needs:
- Combine stdout and stderr into one file (overwrites existing file):
Theperl simplecalc.pl 4 2 > my.log 2>&12>&1tells the shell to send stderr (file descriptor 2) to the same destination as stdout (file descriptor 1). - Split stdout and stderr into separate files:
perl simplecalc.pl 4 2 > stdout.log 2> stderr.log - Append output to a file (instead of overwriting):
perl simplecalc.pl 4 2 >> my.log 2>&1 - Combine with your script's parameters: For example, enable verbose mode and support logging in one go:
perl simplecalc.pl 4 2 1 1 >> support_logs.log 2>&1
If you want simplecalc.pl to handle redirection automatically (based on the $GET_SUPPORT_FILE flag, for example), add these subroutines and integrate them into your code:
Step 1: Add the Redirection Subroutines
Insert these at the top of your script (after the use statements):
# Subroutine to redirect STDOUT and STDERR to a specified file sub redirect_output_to_file { my ($log_file) = @_; # Open log file in append mode (use '>' instead of '>>' to overwrite) open my $stdout_fh, '>>', $log_file or die "Failed to open $log_file for stdout: $!"; open my $stderr_fh, '>>', $log_file or die "Failed to open $log_file for stderr: $!"; # Enable autoflush to avoid buffered output (critical for real-time logs) select $stdout_fh; $| = 1; select $stderr_fh; $| = 1; # Save original file handles to restore later if needed our ($ORIG_STDOUT, $ORIG_STDERR); open $ORIG_STDOUT, '>&STDOUT' or die "Couldn't save original STDOUT: $!"; open $ORIG_STDERR, '>&STDERR' or die "Couldn't save original STDERR: $!"; # Redirect the actual output streams open STDOUT, '>&', $stdout_fh or die "Failed to redirect STDOUT: $!"; open STDERR, '>&', $stderr_fh or die "Failed to redirect STDERR: $!"; } # Subroutine to restore STDOUT/STDERR to their original destinations sub restore_output { our ($ORIG_STDOUT, $ORIG_STDERR); open STDOUT, '>&', $ORIG_STDOUT or die "Couldn't restore STDOUT: $!"; open STDERR, '>&', $ORIG_STDERR or die "Couldn't restore STDERR: $!"; close $ORIG_STDOUT; close $ORIG_STDERR; }
Step 2: Integrate with simplecalc.pl's Support Flag
Update the support-file handling section of your script to trigger redirection when $GET_SUPPORT_FILE is set:
# Handling of the support-file starts here =========== if ($GET_SUPPORT_FILE) { my $target_log = $filename || 'my.log'; # Use default if no filename is set redirect_output_to_file($target_log); print STDOUT "Support mode activated: all output will be logged to $target_log\n"; print STDERR "This error message will also appear in the log file\n"; } # ... (keep your existing calculation logic here) ... # Optional: Restore output to console before exiting (if needed) if ($GET_SUPPORT_FILE) { restore_output(); print "Output restored to console\n"; # This will print to terminal, not the log } # Exit handling exit $exit // $OK;
- Buffering: The
$| = 1lines disable output buffering, so logs are written immediately instead of waiting for a buffer to fill. This is essential for debugging or real-time monitoring. - Error Handling: Always check for
openfailures withor die—this prevents silent failures if the script can't write to the log file. - Testing: Run
perl simplecalc.pl 4 2 0 1to test support mode, then checkmy.logto confirm both stdout and stderr are captured.
内容的提问来源于stack exchange,提问作者lanti

