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
|
|
964
|
use v5.12.5; |
|
58
|
|
|
|
|
266
|
|
8
|
58
|
|
|
58
|
|
376
|
use warnings; |
|
58
|
|
|
|
|
169
|
|
|
58
|
|
|
|
|
3065
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '1.14.2.2'; # TRIAL VERSION |
11
|
|
|
|
|
|
|
|
12
|
58
|
|
|
58
|
|
406
|
use Rex::Logger; |
|
58
|
|
|
|
|
195
|
|
|
58
|
|
|
|
|
440
|
|
13
|
58
|
|
|
58
|
|
2142
|
use Rex::Commands; |
|
58
|
|
|
|
|
311
|
|
|
58
|
|
|
|
|
2025
|
|
14
|
|
|
|
|
|
|
|
15
|
58
|
|
|
58
|
|
481
|
use English qw(-no_match_vars); |
|
58
|
|
|
|
|
213
|
|
|
58
|
|
|
|
|
1207
|
|
16
|
58
|
|
|
58
|
|
39832
|
use Symbol 'gensym'; |
|
58
|
|
|
|
|
151
|
|
|
58
|
|
|
|
|
5204
|
|
17
|
58
|
|
|
58
|
|
742
|
use IPC::Open3; |
|
58
|
|
|
|
|
178417
|
|
|
58
|
|
|
|
|
3679
|
|
18
|
58
|
|
|
58
|
|
814
|
use IO::Select; |
|
58
|
|
|
|
|
106514
|
|
|
58
|
|
|
|
|
3194
|
|
19
|
58
|
|
|
58
|
|
850
|
use Rex::Interface::Exec::IOReader; |
|
58
|
|
|
|
|
218
|
|
|
58
|
|
|
|
|
879
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# Use 'parent' is recommended, but from Perl 5.10.1 its in core |
22
|
58
|
|
|
58
|
|
2330
|
use base qw(Rex::Interface::Exec::Base Rex::Interface::Exec::IOReader); |
|
58
|
|
|
|
|
168
|
|
|
58
|
|
|
|
|
3425
|
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub new { |
25
|
2179
|
|
|
2179
|
0
|
10489
|
my $that = shift; |
26
|
2179
|
|
33
|
|
|
18498
|
my $proto = ref($that) || $that; |
27
|
2179
|
|
|
|
|
6448
|
my $self = {@_}; |
28
|
|
|
|
|
|
|
|
29
|
2179
|
|
|
|
|
4986
|
bless( $self, $proto ); |
30
|
|
|
|
|
|
|
|
31
|
2179
|
|
|
|
|
8896
|
return $self; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub set_env { |
35
|
10
|
|
|
10
|
0
|
26
|
my ( $self, $env ) = @_; |
36
|
10
|
|
|
|
|
49
|
my $cmd = undef; |
37
|
|
|
|
|
|
|
|
38
|
10
|
50
|
|
|
|
42
|
die("Error: env must be a hash") |
39
|
|
|
|
|
|
|
if ( ref $env ne "HASH" ); |
40
|
|
|
|
|
|
|
|
41
|
10
|
|
|
|
|
107
|
while ( my ( $k, $v ) = each(%$env) ) { |
42
|
17
|
|
|
|
|
160
|
$cmd .= "export $k='$v'; "; |
43
|
|
|
|
|
|
|
} |
44
|
10
|
|
|
|
|
48
|
$self->{env} = $cmd; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub exec { |
48
|
1152
|
|
|
1152
|
0
|
8369
|
my ( $self, $cmd, $path, $option ) = @_; |
49
|
|
|
|
|
|
|
|
50
|
1152
|
|
|
|
|
3261
|
my ( $out, $err, $pid ); |
51
|
|
|
|
|
|
|
|
52
|
1152
|
100
|
|
|
|
5215
|
if ( exists $option->{cwd} ) { |
53
|
10
|
50
|
|
|
|
108
|
my $cd_cmd = $OSNAME eq 'MSWin32' ? 'cd /d' : 'cd'; |
54
|
10
|
|
|
|
|
144
|
$cmd = "$cd_cmd " . $option->{cwd} . " && $cmd"; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
1152
|
50
|
|
|
|
3232
|
if ( exists $option->{path} ) { |
58
|
0
|
|
|
|
|
0
|
$path = $option->{path}; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
1152
|
100
|
|
|
|
4047
|
if ( exists $option->{env} ) { |
62
|
10
|
|
|
|
|
73
|
$self->set_env( $option->{env} ); |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
1152
|
50
|
|
|
|
2906
|
if ( exists $option->{format_cmd} ) { |
66
|
0
|
|
|
|
|
0
|
$option->{format_cmd} =~ s/\{\{CMD\}\}/$cmd/; |
67
|
0
|
|
|
|
|
0
|
$cmd = $option->{format_cmd}; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
1152
|
|
|
|
|
4507
|
Rex::Commands::profiler()->start("exec: $cmd"); |
71
|
1152
|
50
|
|
|
|
11341
|
if ( $^O !~ m/^MSWin/ ) { |
72
|
1152
|
100
|
|
|
|
3698
|
if ($path) { $path = "PATH=$path" } |
|
921
|
|
|
|
|
3102
|
|
73
|
1152
|
|
100
|
|
|
5647
|
$path ||= ""; |
74
|
|
|
|
|
|
|
|
75
|
1152
|
|
|
|
|
6710
|
my $new_cmd = "LC_ALL=C $cmd"; |
76
|
1152
|
100
|
|
|
|
3549
|
if ($path) { |
77
|
921
|
|
|
|
|
3466
|
$new_cmd = "export $path ; $new_cmd"; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
1152
|
100
|
|
|
|
3686
|
if ( $self->{env} ) { |
81
|
9
|
|
|
|
|
31
|
$new_cmd = $self->{env} . " $new_cmd"; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
1152
|
50
|
|
|
|
13932
|
if ( Rex::Config->get_source_global_profile ) { |
85
|
0
|
|
|
|
|
0
|
$new_cmd = ". /etc/profile >/dev/null 2>&1; $new_cmd"; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
1152
|
|
|
|
|
3311
|
$cmd = $new_cmd; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
1152
|
|
|
|
|
11165
|
Rex::Logger::debug("Executing: $cmd"); |
92
|
|
|
|
|
|
|
|
93
|
1152
|
|
|
|
|
4507
|
( $out, $err ) = $self->_exec( $cmd, $option ); |
94
|
|
|
|
|
|
|
|
95
|
1152
|
100
|
|
|
|
19332
|
Rex::Logger::debug($out) if ($out); |
96
|
1152
|
100
|
|
|
|
3889
|
if ($err) { |
97
|
2
|
|
|
|
|
23
|
Rex::Logger::debug("========= ERR ============"); |
98
|
2
|
|
|
|
|
12
|
Rex::Logger::debug($err); |
99
|
2
|
|
|
|
|
5
|
Rex::Logger::debug("========= ERR ============"); |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
1152
|
|
|
|
|
23887
|
Rex::Commands::profiler()->end("exec: $cmd"); |
103
|
|
|
|
|
|
|
|
104
|
1152
|
100
|
|
|
|
5175
|
if (wantarray) { return ( $out, $err ); } |
|
922
|
|
|
|
|
10484
|
|
105
|
|
|
|
|
|
|
|
106
|
230
|
|
|
|
|
4710
|
return $out; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub can_run { |
110
|
555
|
|
|
555
|
0
|
2426
|
my ( $self, $commands_to_check, $check_with_command ) = @_; |
111
|
|
|
|
|
|
|
|
112
|
555
|
50
|
33
|
|
|
14562
|
$check_with_command ||= $^O =~ /^MSWin/i ? 'where' : 'which'; |
113
|
|
|
|
|
|
|
|
114
|
555
|
|
|
|
|
4639
|
return $self->SUPER::can_run( $commands_to_check, $check_with_command ); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub _exec { |
118
|
1152
|
|
|
1152
|
|
3368
|
my ( $self, $cmd, $option ) = @_; |
119
|
|
|
|
|
|
|
|
120
|
1152
|
|
|
|
|
3301
|
my ( $pid, $writer, $reader, $error, $out, $err ); |
121
|
1152
|
|
|
|
|
11418
|
$error = gensym; |
122
|
|
|
|
|
|
|
|
123
|
1152
|
100
|
66
|
|
|
76783
|
if ( $^O !~ m/^MSWin/ && Rex::Config->get_no_tty ) { |
124
|
2
|
|
|
|
|
24
|
$pid = open3( $writer, $reader, $error, $cmd ); |
125
|
|
|
|
|
|
|
|
126
|
2
|
|
|
|
|
10210
|
( $out, $err ) = $self->io_read( $reader, $error, $pid, $option ); |
127
|
|
|
|
|
|
|
|
128
|
2
|
50
|
|
|
|
66
|
waitpid( $pid, 0 ) or die($!); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
else { |
131
|
1150
|
50
|
|
|
|
4732602
|
$pid = open( my $fh, "-|", "$cmd 2>&1" ) or die($!); |
132
|
1150
|
|
|
|
|
4552487
|
while (<$fh>) { |
133
|
5994
|
|
|
|
|
21018
|
$out .= $_; |
134
|
5994
|
|
|
|
|
13556
|
chomp; |
135
|
|
|
|
|
|
|
$self->execute_line_based_operation( $_, $option ) |
136
|
5994
|
50
|
|
|
|
35017
|
&& do { kill( 'KILL', $pid ); last }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
137
|
|
|
|
|
|
|
} |
138
|
1150
|
50
|
|
|
|
97178
|
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
|
1152
|
|
|
|
|
22974
|
$? >>= 8; |
146
|
|
|
|
|
|
|
|
147
|
1152
|
|
|
|
|
45381
|
return ( $out, $err ); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
1; |