line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# (c) Jan Gehring |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Rex::Interface::Exec::Local; |
6
|
|
|
|
|
|
|
|
7
|
58
|
|
|
58
|
|
872
|
use v5.12.5; |
|
58
|
|
|
|
|
232
|
|
8
|
58
|
|
|
58
|
|
319
|
use warnings; |
|
58
|
|
|
|
|
175
|
|
|
58
|
|
|
|
|
3347
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '1.14.2.3'; # TRIAL VERSION |
11
|
|
|
|
|
|
|
|
12
|
58
|
|
|
58
|
|
431
|
use Rex::Logger; |
|
58
|
|
|
|
|
187
|
|
|
58
|
|
|
|
|
437
|
|
13
|
58
|
|
|
58
|
|
2226
|
use Rex::Commands; |
|
58
|
|
|
|
|
386
|
|
|
58
|
|
|
|
|
1983
|
|
14
|
|
|
|
|
|
|
|
15
|
58
|
|
|
58
|
|
533
|
use English qw(-no_match_vars); |
|
58
|
|
|
|
|
171
|
|
|
58
|
|
|
|
|
1349
|
|
16
|
58
|
|
|
58
|
|
38293
|
use Symbol 'gensym'; |
|
58
|
|
|
|
|
197
|
|
|
58
|
|
|
|
|
5153
|
|
17
|
58
|
|
|
58
|
|
743
|
use IPC::Open3; |
|
58
|
|
|
|
|
177403
|
|
|
58
|
|
|
|
|
3478
|
|
18
|
58
|
|
|
58
|
|
826
|
use IO::Select; |
|
58
|
|
|
|
|
103347
|
|
|
58
|
|
|
|
|
3232
|
|
19
|
58
|
|
|
58
|
|
819
|
use Rex::Interface::Exec::IOReader; |
|
58
|
|
|
|
|
210
|
|
|
58
|
|
|
|
|
806
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# Use 'parent' is recommended, but from Perl 5.10.1 its in core |
22
|
58
|
|
|
58
|
|
2357
|
use base qw(Rex::Interface::Exec::Base Rex::Interface::Exec::IOReader); |
|
58
|
|
|
|
|
157
|
|
|
58
|
|
|
|
|
3184
|
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub new { |
25
|
2178
|
|
|
2178
|
0
|
9826
|
my $that = shift; |
26
|
2178
|
|
33
|
|
|
16002
|
my $proto = ref($that) || $that; |
27
|
2178
|
|
|
|
|
6405
|
my $self = {@_}; |
28
|
|
|
|
|
|
|
|
29
|
2178
|
|
|
|
|
5063
|
bless( $self, $proto ); |
30
|
|
|
|
|
|
|
|
31
|
2178
|
|
|
|
|
8398
|
return $self; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub set_env { |
35
|
10
|
|
|
10
|
0
|
29
|
my ( $self, $env ) = @_; |
36
|
10
|
|
|
|
|
36
|
my $cmd = undef; |
37
|
|
|
|
|
|
|
|
38
|
10
|
50
|
|
|
|
55
|
die("Error: env must be a hash") |
39
|
|
|
|
|
|
|
if ( ref $env ne "HASH" ); |
40
|
|
|
|
|
|
|
|
41
|
10
|
|
|
|
|
142
|
while ( my ( $k, $v ) = each(%$env) ) { |
42
|
17
|
|
|
|
|
165
|
$cmd .= "export $k='$v'; "; |
43
|
|
|
|
|
|
|
} |
44
|
10
|
|
|
|
|
56
|
$self->{env} = $cmd; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub exec { |
48
|
1151
|
|
|
1151
|
0
|
7981
|
my ( $self, $cmd, $path, $option ) = @_; |
49
|
|
|
|
|
|
|
|
50
|
1151
|
|
|
|
|
3200
|
my ( $out, $err, $pid ); |
51
|
|
|
|
|
|
|
|
52
|
1151
|
100
|
|
|
|
3950
|
if ( exists $option->{cwd} ) { |
53
|
10
|
50
|
|
|
|
120
|
my $cd_cmd = $OSNAME eq 'MSWin32' ? 'cd /d' : 'cd'; |
54
|
10
|
|
|
|
|
75
|
$cmd = "$cd_cmd " . $option->{cwd} . " && $cmd"; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
1151
|
50
|
|
|
|
3014
|
if ( exists $option->{path} ) { |
58
|
0
|
|
|
|
|
0
|
$path = $option->{path}; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
1151
|
100
|
|
|
|
2967
|
if ( exists $option->{env} ) { |
62
|
10
|
|
|
|
|
45
|
$self->set_env( $option->{env} ); |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
1151
|
50
|
|
|
|
2612
|
if ( exists $option->{format_cmd} ) { |
66
|
0
|
|
|
|
|
0
|
$option->{format_cmd} =~ s/\{\{CMD\}\}/$cmd/; |
67
|
0
|
|
|
|
|
0
|
$cmd = $option->{format_cmd}; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
1151
|
|
|
|
|
4353
|
Rex::Commands::profiler()->start("exec: $cmd"); |
71
|
1151
|
50
|
|
|
|
10693
|
if ( $^O !~ m/^MSWin/ ) { |
72
|
1151
|
100
|
|
|
|
3570
|
if ($path) { $path = "PATH=$path" } |
|
920
|
|
|
|
|
3050
|
|
73
|
1151
|
|
100
|
|
|
5809
|
$path ||= ""; |
74
|
|
|
|
|
|
|
|
75
|
1151
|
|
|
|
|
7741
|
my $new_cmd = "LC_ALL=C $cmd"; |
76
|
1151
|
100
|
|
|
|
3627
|
if ($path) { |
77
|
920
|
|
|
|
|
3450
|
$new_cmd = "export $path ; $new_cmd"; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
1151
|
100
|
|
|
|
3762
|
if ( $self->{env} ) { |
81
|
9
|
|
|
|
|
33
|
$new_cmd = $self->{env} . " $new_cmd"; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
1151
|
50
|
|
|
|
13750
|
if ( Rex::Config->get_source_global_profile ) { |
85
|
0
|
|
|
|
|
0
|
$new_cmd = ". /etc/profile >/dev/null 2>&1; $new_cmd"; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
1151
|
|
|
|
|
3139
|
$cmd = $new_cmd; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
1151
|
|
|
|
|
10869
|
Rex::Logger::debug("Executing: $cmd"); |
92
|
|
|
|
|
|
|
|
93
|
1151
|
|
|
|
|
5922
|
( $out, $err ) = $self->_exec( $cmd, $option ); |
94
|
|
|
|
|
|
|
|
95
|
1151
|
100
|
|
|
|
18061
|
Rex::Logger::debug($out) if ($out); |
96
|
1151
|
100
|
|
|
|
4986
|
if ($err) { |
97
|
2
|
|
|
|
|
21
|
Rex::Logger::debug("========= ERR ============"); |
98
|
2
|
|
|
|
|
10
|
Rex::Logger::debug($err); |
99
|
2
|
|
|
|
|
12
|
Rex::Logger::debug("========= ERR ============"); |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
1151
|
|
|
|
|
23009
|
Rex::Commands::profiler()->end("exec: $cmd"); |
103
|
|
|
|
|
|
|
|
104
|
1151
|
100
|
|
|
|
4885
|
if (wantarray) { return ( $out, $err ); } |
|
921
|
|
|
|
|
11502
|
|
105
|
|
|
|
|
|
|
|
106
|
230
|
|
|
|
|
4059
|
return $out; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub can_run { |
110
|
555
|
|
|
555
|
0
|
2219
|
my ( $self, $commands_to_check, $check_with_command ) = @_; |
111
|
|
|
|
|
|
|
|
112
|
555
|
50
|
33
|
|
|
13624
|
$check_with_command ||= $^O =~ /^MSWin/i ? 'where' : 'which'; |
113
|
|
|
|
|
|
|
|
114
|
555
|
|
|
|
|
5000
|
return $self->SUPER::can_run( $commands_to_check, $check_with_command ); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub _exec { |
118
|
1151
|
|
|
1151
|
|
3768
|
my ( $self, $cmd, $option ) = @_; |
119
|
|
|
|
|
|
|
|
120
|
1151
|
|
|
|
|
2606
|
my ( $pid, $writer, $reader, $error, $out, $err ); |
121
|
1151
|
|
|
|
|
10764
|
$error = gensym; |
122
|
|
|
|
|
|
|
|
123
|
1151
|
100
|
66
|
|
|
72520
|
if ( $^O !~ m/^MSWin/ && Rex::Config->get_no_tty ) { |
124
|
2
|
|
|
|
|
24
|
$pid = open3( $writer, $reader, $error, $cmd ); |
125
|
|
|
|
|
|
|
|
126
|
2
|
|
|
|
|
9055
|
( $out, $err ) = $self->io_read( $reader, $error, $pid, $option ); |
127
|
|
|
|
|
|
|
|
128
|
2
|
50
|
|
|
|
68
|
waitpid( $pid, 0 ) or die($!); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
else { |
131
|
1149
|
50
|
|
|
|
3914028
|
$pid = open( my $fh, "-|", "$cmd 2>&1" ) or die($!); |
132
|
1149
|
|
|
|
|
4254111
|
while (<$fh>) { |
133
|
5993
|
|
|
|
|
21205
|
$out .= $_; |
134
|
5993
|
|
|
|
|
13005
|
chomp; |
135
|
|
|
|
|
|
|
$self->execute_line_based_operation( $_, $option ) |
136
|
5993
|
50
|
|
|
|
34178
|
&& do { kill( 'KILL', $pid ); last }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
137
|
|
|
|
|
|
|
} |
138
|
1149
|
50
|
|
|
|
92574
|
waitpid( $pid, 0 ) or die($!); |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# we need to bitshift $? so that $? contains the right (and for all |
143
|
|
|
|
|
|
|
# connection methods the same) exit code after a run()/i_run() call. |
144
|
|
|
|
|
|
|
# this is for the user, so that he can query $? in his task. |
145
|
1151
|
|
|
|
|
23140
|
$? >>= 8; |
146
|
|
|
|
|
|
|
|
147
|
1151
|
|
|
|
|
42961
|
return ( $out, $err ); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
1; |