line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
6
|
|
|
6
|
|
266913
|
use strict; |
|
6
|
|
|
|
|
17
|
|
|
6
|
|
|
|
|
261
|
|
2
|
6
|
|
|
6
|
|
35
|
use warnings; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
2910
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package IO::CaptureOutput; |
5
|
|
|
|
|
|
|
# ABSTRACT: capture STDOUT and STDERR from Perl code, subprocesses or XS |
6
|
|
|
|
|
|
|
our $VERSION = '1.1103'; # VERSION |
7
|
|
|
|
|
|
|
|
8
|
6
|
|
|
6
|
|
39
|
use vars qw/@ISA @EXPORT_OK %EXPORT_TAGS $CarpLevel/; |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
657
|
|
9
|
6
|
|
|
6
|
|
33
|
use Exporter; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
292
|
|
10
|
6
|
|
|
6
|
|
34
|
use Carp qw/croak/; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
18300
|
|
11
|
|
|
|
|
|
|
@ISA = 'Exporter'; |
12
|
|
|
|
|
|
|
@EXPORT_OK = qw/capture capture_exec qxx capture_exec_combined qxy/; |
13
|
|
|
|
|
|
|
%EXPORT_TAGS = (all => \@EXPORT_OK); |
14
|
|
|
|
|
|
|
$CarpLevel = 0; # help capture report errors at the right level |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub _capture (&@) { ## no critic |
17
|
60
|
|
|
60
|
|
135
|
my ($code, $output, $error, $output_file, $error_file) = @_; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# check for valid combinations of input |
20
|
|
|
|
|
|
|
{ |
21
|
60
|
|
|
|
|
96
|
local $Carp::CarpLevel = 1; |
|
60
|
|
|
|
|
181
|
|
22
|
60
|
|
|
|
|
221
|
my $error = _validate($output, $error, $output_file, $error_file); |
23
|
60
|
100
|
|
|
|
697
|
croak $error if $error; |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# if either $output or $error are defined, then we need a variable for |
27
|
|
|
|
|
|
|
# results; otherwise we only capture to files and don't waste memory |
28
|
58
|
100
|
100
|
|
|
216
|
if ( defined $output || defined $error ) { |
29
|
48
|
|
|
|
|
90
|
for ($output, $error) { |
30
|
96
|
100
|
|
|
|
253
|
$_ = \do { my $s; $s = ''} unless ref $_; |
|
10
|
|
|
|
|
14
|
|
|
10
|
|
|
|
|
25
|
|
31
|
96
|
100
|
100
|
|
|
605
|
$$_ = '' if $_ != \undef && !defined($$_); |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# merge if same refs for $output and $error or if both are undef -- |
36
|
|
|
|
|
|
|
# i.e. capture \&foo, undef, undef, $merged_file |
37
|
|
|
|
|
|
|
# this means capturing into separate files *requires* at least one |
38
|
|
|
|
|
|
|
# capture variable |
39
|
58
|
|
100
|
|
|
736
|
my $should_merge = |
40
|
|
|
|
|
|
|
(defined $error && defined $output && $output == $error) || |
41
|
|
|
|
|
|
|
( !defined $output && !defined $error ) || |
42
|
|
|
|
|
|
|
0; |
43
|
|
|
|
|
|
|
|
44
|
58
|
|
|
|
|
131
|
my ($capture_out, $capture_err); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# undef means capture anonymously; anything other than \undef means |
47
|
|
|
|
|
|
|
# capture to that ref; \undef means skip capture |
48
|
58
|
100
|
100
|
|
|
304
|
if ( !defined $output || $output != \undef ) { |
49
|
56
|
|
|
|
|
594
|
$capture_out = IO::CaptureOutput::_proxy->new( |
50
|
|
|
|
|
|
|
'STDOUT', $output, undef, $output_file |
51
|
|
|
|
|
|
|
); |
52
|
|
|
|
|
|
|
} |
53
|
58
|
100
|
100
|
|
|
355
|
if ( !defined $error || $error != \undef ) { |
54
|
56
|
100
|
|
|
|
731
|
$capture_err = IO::CaptureOutput::_proxy->new( |
55
|
|
|
|
|
|
|
'STDERR', $error, ($should_merge ? 'STDOUT' : undef), $error_file |
56
|
|
|
|
|
|
|
); |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# now that output capture is setup, call the subroutine |
60
|
|
|
|
|
|
|
# results get read when IO::CaptureOutput::_proxy objects go out of scope |
61
|
58
|
|
|
|
|
380
|
&$code(); |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# Extra indirection for symmetry with capture_exec, etc. Gets error reporting |
65
|
|
|
|
|
|
|
# to the right level |
66
|
|
|
|
|
|
|
sub capture (&@) { ## no critic |
67
|
50
|
|
|
50
|
1
|
129042
|
return &_capture; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub capture_exec { |
71
|
5
|
|
|
5
|
1
|
31933
|
my @args = @_; |
72
|
5
|
|
|
|
|
11
|
my ($output, $error); |
73
|
5
|
|
|
5
|
|
67
|
my $exit = _capture sub { system _shell_quote(@args) }, \$output, \$error; |
|
5
|
|
|
|
|
101
|
|
74
|
5
|
100
|
|
|
|
327
|
my $success = ($exit == 0 ) ? 1 : 0 ; |
75
|
5
|
|
|
|
|
32
|
$? = $exit; |
76
|
5
|
100
|
|
|
|
6383
|
return wantarray ? ($output, $error, $success, $exit) : $output; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
*qxx = \&capture_exec; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub capture_exec_combined { |
82
|
5
|
|
|
5
|
1
|
20391
|
my @args = @_; |
83
|
5
|
|
|
|
|
14
|
my $output; |
84
|
5
|
|
|
5
|
|
78
|
my $exit = _capture sub { system _shell_quote(@args) }, \$output, \$output; |
|
5
|
|
|
|
|
27
|
|
85
|
5
|
100
|
|
|
|
223
|
my $success = ($exit == 0 ) ? 1 : 0 ; |
86
|
5
|
|
|
|
|
54
|
$? = $exit; |
87
|
5
|
100
|
|
|
|
142
|
return wantarray ? ($output, $success, $exit) : $output; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
*qxy = \&capture_exec_combined; |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# extra quoting required on Win32 systems |
93
|
10
|
|
|
10
|
|
165236
|
*_shell_quote = ($^O =~ /MSWin32/) ? \&_shell_quote_win32 : sub {@_}; |
94
|
|
|
|
|
|
|
sub _shell_quote_win32 { |
95
|
0
|
|
|
0
|
|
0
|
my @args; |
96
|
0
|
|
|
|
|
0
|
for (@_) { |
97
|
0
|
0
|
|
|
|
0
|
if (/[ \"]/) { # TODO: check if ^ requires escaping |
98
|
0
|
|
|
|
|
0
|
(my $escaped = $_) =~ s/([\"])/\\$1/g; |
99
|
0
|
|
|
|
|
0
|
push @args, '"' . $escaped . '"'; |
100
|
0
|
|
|
|
|
0
|
next; |
101
|
|
|
|
|
|
|
} |
102
|
0
|
|
|
|
|
0
|
push @args, $_ |
103
|
|
|
|
|
|
|
} |
104
|
0
|
|
|
|
|
0
|
return @args; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# detect errors and return an error message or empty string; |
108
|
|
|
|
|
|
|
sub _validate { |
109
|
60
|
|
|
60
|
|
127
|
my ($output, $error, $output_file, $error_file) = @_; |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# default to "ok" |
112
|
60
|
|
|
|
|
138
|
my $msg = q{}; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# \$out, \$out, $outfile, $errfile |
115
|
60
|
100
|
100
|
|
|
1282
|
if ( defined $output && defined $error |
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
116
|
|
|
|
|
|
|
&& defined $output_file && defined $error_file |
117
|
|
|
|
|
|
|
&& $output == $error |
118
|
|
|
|
|
|
|
&& $output != \undef |
119
|
|
|
|
|
|
|
&& $output_file ne $error_file |
120
|
|
|
|
|
|
|
) { |
121
|
1
|
|
|
|
|
3
|
$msg = "Merged STDOUT and STDERR, but specified different output and error files"; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
# undef, undef, $outfile, $errfile |
124
|
|
|
|
|
|
|
elsif ( !defined $output && !defined $error |
125
|
|
|
|
|
|
|
&& defined $output_file && defined $error_file |
126
|
|
|
|
|
|
|
&& $output_file ne $error_file |
127
|
|
|
|
|
|
|
) { |
128
|
1
|
|
|
|
|
3
|
$msg = "Merged STDOUT and STDERR, but specified different output and error files"; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
60
|
|
|
|
|
180
|
return $msg; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
# Captures everything printed to a filehandle for the lifetime of the object |
135
|
|
|
|
|
|
|
# and then transfers it to a scalar reference |
136
|
|
|
|
|
|
|
package IO::CaptureOutput::_proxy; |
137
|
6
|
|
|
6
|
|
10114
|
use File::Temp 0.16 'tempfile'; |
|
6
|
|
|
|
|
231315
|
|
|
6
|
|
|
|
|
1348
|
|
138
|
6
|
|
|
6
|
|
56
|
use File::Basename qw/basename/; |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
824
|
|
139
|
6
|
|
|
6
|
|
39
|
use Symbol qw/gensym qualify qualify_to_ref/; |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
370
|
|
140
|
6
|
|
|
6
|
|
34
|
use Carp; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
995
|
|
141
|
|
|
|
|
|
|
|
142
|
110
|
50
|
|
110
|
|
1091
|
sub _is_wperl { $^O eq 'MSWin32' && basename($^X) eq 'wperl.exe' } |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub new { |
145
|
112
|
|
|
112
|
|
167
|
my $class = shift; |
146
|
112
|
|
|
|
|
245
|
my ($orig_fh, $capture_var, $merge_fh, $capture_file) = @_; |
147
|
112
|
|
|
|
|
389
|
$orig_fh = qualify($orig_fh); # e.g. main::STDOUT |
148
|
112
|
|
|
|
|
2117
|
my $fhref = qualify_to_ref($orig_fh); # e.g. \*STDOUT |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# Duplicate the filehandle |
151
|
112
|
|
|
|
|
1165
|
my $saved_fh; |
152
|
|
|
|
|
|
|
{ |
153
|
6
|
|
|
6
|
|
113
|
no strict 'refs'; ## no critic - needed for 5.005 |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
1881
|
|
|
112
|
|
|
|
|
281
|
|
154
|
112
|
100
|
66
|
|
|
693
|
if ( defined fileno($orig_fh) && ! _is_wperl() ) { |
155
|
110
|
|
|
|
|
291
|
$saved_fh = gensym; |
156
|
110
|
50
|
|
|
|
3565
|
open $saved_fh, ">&$orig_fh" or croak "Can't redirect <$orig_fh> - $!"; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# Create replacement filehandle if not merging |
161
|
112
|
|
|
|
|
173
|
my ($newio_fh, $newio_file); |
162
|
112
|
100
|
|
|
|
208
|
if ( ! $merge_fh ) { |
163
|
92
|
|
|
|
|
225
|
$newio_fh = gensym; |
164
|
92
|
100
|
|
|
|
955
|
if ($capture_file) { |
165
|
19
|
|
|
|
|
32
|
$newio_file = $capture_file; |
166
|
|
|
|
|
|
|
} else { |
167
|
73
|
|
|
|
|
621
|
(undef, $newio_file) = tempfile; |
168
|
|
|
|
|
|
|
} |
169
|
92
|
50
|
|
|
|
44123
|
open $newio_fh, "+>$newio_file" or croak "Can't write temp file for $orig_fh - $!"; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
else { |
172
|
20
|
|
|
|
|
68
|
$newio_fh = qualify($merge_fh); |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# Redirect (or merge) |
176
|
|
|
|
|
|
|
{ |
177
|
6
|
|
|
6
|
|
33
|
no strict 'refs'; ## no critic -- needed for 5.005 |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
2407
|
|
|
112
|
|
|
|
|
385
|
|
178
|
112
|
50
|
|
|
|
2908
|
open $fhref, ">&".fileno($newio_fh) or croak "Can't redirect $orig_fh - $!"; |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
112
|
|
|
|
|
847
|
bless [$$, $orig_fh, $saved_fh, $capture_var, $newio_fh, $newio_file, $capture_file], $class; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub DESTROY { |
185
|
112
|
|
|
112
|
|
295374
|
my $self = shift; |
186
|
|
|
|
|
|
|
|
187
|
112
|
|
|
|
|
1060
|
my ($pid, $orig_fh, $saved_fh, $capture_var, $newio_fh, |
188
|
|
|
|
|
|
|
$newio_file, $capture_file) = @$self; |
189
|
112
|
100
|
|
|
|
1579
|
return unless $pid eq $$; # only cleanup in the process that is capturing |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# restore the original filehandle |
192
|
110
|
|
|
|
|
695
|
my $fh_ref = Symbol::qualify_to_ref($orig_fh); |
193
|
110
|
|
|
|
|
3063
|
select((select ($fh_ref), $|=1)[0]); |
194
|
110
|
100
|
|
|
|
479
|
if (defined $saved_fh) { |
195
|
108
|
50
|
|
|
|
4210
|
open $fh_ref, ">&". fileno($saved_fh) or croak "Can't restore $orig_fh - $!"; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
else { |
198
|
2
|
|
|
|
|
11
|
close $fh_ref; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
# transfer captured data to the scalar reference if we didn't merge |
202
|
|
|
|
|
|
|
# $newio_file is undef if this file handle is merged to another |
203
|
110
|
100
|
100
|
|
|
963
|
if (ref $capture_var && $newio_file) { |
204
|
|
|
|
|
|
|
# some versions of perl complain about reading from fd 1 or 2 |
205
|
|
|
|
|
|
|
# which could happen if STDOUT and STDERR were closed when $newio |
206
|
|
|
|
|
|
|
# was opened, so we just squelch warnings here and continue |
207
|
80
|
|
|
|
|
329
|
local $^W; |
208
|
80
|
|
|
|
|
454
|
seek $newio_fh, 0, 0; |
209
|
80
|
|
|
|
|
112
|
$$capture_var = do {local $/; <$newio_fh>}; |
|
80
|
|
|
|
|
361
|
|
|
80
|
|
|
|
|
2887
|
|
210
|
|
|
|
|
|
|
} |
211
|
110
|
100
|
|
|
|
1473
|
close $newio_fh if $newio_file; |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# Cleanup |
214
|
110
|
100
|
66
|
|
|
2813
|
return unless defined $newio_file && -e $newio_file; |
215
|
90
|
100
|
|
|
|
392
|
return if $capture_file; # the "temp" file was explicitly named |
216
|
71
|
50
|
|
|
|
15173
|
unlink $newio_file or carp "Couldn't remove temp file '$newio_file' - $!"; |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
1; |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
__END__ |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=pod |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=encoding UTF-8 |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=head1 NAME |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
IO::CaptureOutput - capture STDOUT and STDERR from Perl code, subprocesses or XS |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=head1 VERSION |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
version 1.1103 |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=head1 SYNOPSIS |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
use IO::CaptureOutput qw(capture qxx qxy); |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
# STDOUT and STDERR separately |
240
|
|
|
|
|
|
|
capture { noisy_sub(@args) } \$stdout, \$stderr; |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
# STDOUT and STDERR together |
243
|
|
|
|
|
|
|
capture { noisy_sub(@args) } \$combined, \$combined; |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# STDOUT and STDERR from external command |
246
|
|
|
|
|
|
|
($stdout, $stderr, $success) = qxx( @cmd ); |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# STDOUT and STDERR together from external command |
249
|
|
|
|
|
|
|
($combined, $success) = qxy( @cmd ); |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=head1 DESCRIPTION |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
B<This module is no longer recommended by the maintainer> - see |
254
|
|
|
|
|
|
|
L<Capture::Tiny> instead. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
This module provides routines for capturing STDOUT and STDERR from perl |
257
|
|
|
|
|
|
|
subroutines, forked system calls (e.g. C<<< system() >>>, C<<< fork() >>>) and from |
258
|
|
|
|
|
|
|
XS or C modules. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=head1 NAME |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=head1 VERSION |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
This documentation describes version %%VERSION%%. |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head1 FUNCTIONS |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
The following functions will be exported on demand. |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head2 capture() |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
capture \&subroutine, \$stdout, \$stderr; |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
Captures everything printed to C<<< STDOUT >>> and C<<< STDERR >>> for the duration of |
275
|
|
|
|
|
|
|
C<<< &subroutine >>>. C<<< $stdout >>> and C<<< $stderr >>> are optional scalars that will contain |
276
|
|
|
|
|
|
|
C<<< STDOUT >>> and C<<< STDERR >>> respectively. |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
C<<< capture() >>> uses a code prototype so the first argument can be specified directly within |
279
|
|
|
|
|
|
|
brackets if desired. |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
# shorthand with prototype |
282
|
|
|
|
|
|
|
capture { print __PACKAGE__ } \$stdout, \$stderr; |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
Returns the return value(s) of C<<< &subroutine >>>. The sub is called in the same |
285
|
|
|
|
|
|
|
context as C<<< capture() >>> was called e.g.: |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
@rv = capture { wantarray } ; # returns true |
288
|
|
|
|
|
|
|
$rv = capture { wantarray } ; # returns defined, but not true |
289
|
|
|
|
|
|
|
capture { wantarray }; # void, returns undef |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
C<<< capture() >>> is able to capture output from subprocesses and C code, which |
292
|
|
|
|
|
|
|
traditional C<<< tie() >>> methods of output capture are unable to do. |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
B<Note:> C<<< capture() >>> will only capture output that has been written or flushed |
295
|
|
|
|
|
|
|
to the filehandle. |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
If the two scalar references refer to the same scalar, then C<<< STDERR >>> will be |
298
|
|
|
|
|
|
|
merged to C<<< STDOUT >>> before capturing and the scalar will hold the combined |
299
|
|
|
|
|
|
|
output of both. |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
capture \&subroutine, \$combined, \$combined; |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
Normally, C<<< capture() >>> uses anonymous, temporary files for capturing output. |
304
|
|
|
|
|
|
|
If desired, specific file names may be provided instead as additional options. |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
capture \&subroutine, \$stdout, \$stderr, $out_file, $err_file; |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
Files provided will be clobbered, overwriting any previous data, but |
309
|
|
|
|
|
|
|
will persist after the call to C<<< capture() >>> for inspection or other manipulation. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
By default, when no references are provided to hold STDOUT or STDERR, output |
312
|
|
|
|
|
|
|
is captured and silently discarded. |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
# Capture STDOUT, discard STDERR |
315
|
|
|
|
|
|
|
capture \&subroutine, \$stdout; |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
# Discard STDOUT, capture STDERR |
318
|
|
|
|
|
|
|
capture \&subroutine, undef, \$stderr; |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
However, even when using C<<< undef >>>, output can be captured to specific files. |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
# Capture STDOUT to a specific file, discard STDERR |
323
|
|
|
|
|
|
|
capture \&subroutine, \$stdout, undef, $outfile; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# Discard STDOUT, capture STDERR to a specific file |
326
|
|
|
|
|
|
|
capture \&subroutine, undef, \$stderr, undef, $err_file; |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
# Discard both, capture merged output to a specific file |
329
|
|
|
|
|
|
|
capture \&subroutine, undef, undef, $mergedfile; |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
It is a fatal error to merge STDOUT and STDERR and request separate, specific |
332
|
|
|
|
|
|
|
files for capture. |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
# ERROR: |
335
|
|
|
|
|
|
|
capture \&subroutine, \$stdout, \$stdout, $out_file, $err_file; |
336
|
|
|
|
|
|
|
capture \&subroutine, undef, undef, $out_file, $err_file; |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
If either STDOUT or STDERR should be passed through to the terminal instead of |
339
|
|
|
|
|
|
|
captured, provide a reference to undef -- C<<< \undef >>> -- instead of a capture |
340
|
|
|
|
|
|
|
variable. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
# Capture STDOUT, display STDERR |
343
|
|
|
|
|
|
|
capture \&subroutine, \$stdout, \undef; |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
# Display STDOUT, capture STDERR |
346
|
|
|
|
|
|
|
capture \&subroutine, \undef, \$stderr; |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=head2 capture_exec() |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
($stdout, $stderr, $success, $exit_code) = capture_exec(@args); |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
Captures and returns the output from C<<< system(@args) >>>. In scalar context, |
353
|
|
|
|
|
|
|
C<<< capture_exec() >>> will return what was printed to C<<< STDOUT >>>. In list context, |
354
|
|
|
|
|
|
|
it returns what was printed to C<<< STDOUT >>> and C<<< STDERR >>> as well as a success |
355
|
|
|
|
|
|
|
flag and the exit value. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
$stdout = capture_exec('perl', '-e', 'print "hello world"'); |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
($stdout, $stderr, $success, $exit_code) = |
360
|
|
|
|
|
|
|
capture_exec('perl', '-e', 'warn "Test"'); |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
C<<< capture_exec >>> passes its arguments to C<<< system() >>> and on MSWin32 will protect |
363
|
|
|
|
|
|
|
arguments with shell quotes if necessary. This makes it a handy and slightly |
364
|
|
|
|
|
|
|
more portable alternative to backticks, piped C<<< open() >>> and C<<< IPC::Open3 >>>. |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
The C<<< $success >>> flag returned will be true if the command ran successfully and |
367
|
|
|
|
|
|
|
false if it did not (if the command could not be run or if it ran and |
368
|
|
|
|
|
|
|
returned a non-zero exit value). On failure, the raw exit value of the |
369
|
|
|
|
|
|
|
C<<< system() >>> call is available both in the C<<< $exit_code >>> returned and in the C<<< $? >>> |
370
|
|
|
|
|
|
|
variable. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
($stdout, $stderr, $success, $exit_code) = |
373
|
|
|
|
|
|
|
capture_exec('perl', '-e', 'warn "Test" and exit 1'); |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
if ( ! $success ) { |
376
|
|
|
|
|
|
|
print "The exit code was " . ($exit_code >> 8) . "\n"; |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
See L<perlvar> for more information on interpreting a child process |
380
|
|
|
|
|
|
|
exit code. |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
=head2 capture_exec_combined() |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
($combined, $success, $exit_code) = capture_exec_combined( |
385
|
|
|
|
|
|
|
'perl', '-e', 'print "hello\n"', 'warn "Test\n" |
386
|
|
|
|
|
|
|
); |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
This is just like C<<< capture_exec() >>>, except that it merges C<<< STDERR >>> with C<<< STDOUT >>> |
389
|
|
|
|
|
|
|
before capturing output. |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
B<Note:> there is no guarantee that text printed to C<<< STDOUT >>> and C<<< STDERR >>> in the |
392
|
|
|
|
|
|
|
subprocess will be appear in order. The actual order will depend on how IO |
393
|
|
|
|
|
|
|
buffering is handled in the subprocess. |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=head2 qxx() |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
This is an alias for C<<< capture_exec() >>>. |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=head2 qxy() |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
This is an alias for C<<< capture_exec_combined() >>>. |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=head1 SEE ALSO |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=over |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
=item * |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
L<Capture::Tiny> |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
=item * |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
L<IPC::Open3> |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
=item * |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
L<IO::Capture> |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=item * |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
L<IO::Utils> |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
=item * |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
L<IPC::System::Simple> |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
=back |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
=head1 SUPPORT |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=head2 Bugs / Feature Requests |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
Please report any bugs or feature requests through the issue tracker |
436
|
|
|
|
|
|
|
at L<https://github.com/dagolden/IO-CaptureOutput/issues>. |
437
|
|
|
|
|
|
|
You will be notified automatically of any progress on your issue. |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=head2 Source Code |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
This is open source software. The code repository is available for |
442
|
|
|
|
|
|
|
public review and contribution under the terms of the license. |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
L<https://github.com/dagolden/IO-CaptureOutput> |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
git clone https://github.com/dagolden/IO-CaptureOutput.git |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=head1 AUTHORS |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=over 4 |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=item * |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
Simon Flack <simonflk@cpan.org> |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
=item * |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
David Golden <dagolden@cpan.org> |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=back |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=head1 CONTRIBUTORS |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=over 4 |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
=item * |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
Olivier Mengué <dolmen@cpan.org> |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=item * |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
Tony Cook <tony@develop-help.com> |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
=item * |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
unknown <dgolden@.(none)> |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
=back |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
This software is copyright (c) 2014 by Simon Flack and David Golden. |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
485
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=cut |