1# 2# (c) Jan Gehring <jan.gehring@gmail.com> 3# 4# vim: set ts=2 sw=2 tw=0: 5# vim: set expandtab: 6 7package Rex::Interface::Exec::Base; 8 9use 5.010001; 10use strict; 11use warnings; 12use Carp; 13use Rex::Helper::Run; 14 15our $VERSION = '1.13.4'; # VERSION 16 17sub new { 18 my $that = shift; 19 my $proto = ref($that) || $that; 20 my $self = {@_}; 21 22 bless( $self, $proto ); 23 24 return $self; 25} 26 27sub exec { die("Must be implemented by Interface Class"); } 28 29sub _continuous_read { 30 my ( $self, $line, $option ) = @_; 31 my $cb = $option->{continuous_read} || undef; 32 33 if ( defined($cb) && ref($cb) eq 'CODE' ) { 34 &$cb($line); 35 } 36} 37 38sub _end_if_matched { 39 my ( $self, $line, $option ) = @_; 40 my $regex = $option->{end_if_matched} || undef; 41 42 if ( defined($regex) && ref($regex) eq 'Regexp' && $line =~ m/$regex/ ) { 43 return 1; 44 } 45 return; 46} 47 48sub execute_line_based_operation { 49 my ( $self, $line, $option ) = @_; 50 51 $self->_continuous_read( $line, $option ); 52 return $self->_end_if_matched( $line, $option ); 53} 54 55sub can_run { 56 my ( $self, $commands_to_check, $check_with_command ) = @_; 57 58 $check_with_command ||= "which"; 59 60 my $exec = Rex::Interface::Exec->create; 61 my $cache = Rex::get_cache(); 62 63 for my $command ( @{$commands_to_check} ) { 64 65 my $cache_key_name = $cache->gen_key_name("can_run.cmd/$command"); 66 if ( $cache->valid($cache_key_name) ) { 67 return $cache->get($cache_key_name); 68 } 69 70 my @output = Rex::Helper::Run::i_run "$check_with_command $command", 71 fail_ok => 1; 72 73 next if ( $? != 0 ); 74 next if ( grep { /^no $command in/ } @output ); # for solaris 75 76 $cache->set( $cache_key_name, $output[0] ); 77 78 return $output[0]; 79 } 80 81 return undef; 82} 83 84sub direct_exec { 85 my ( $self, $exec, $option ) = @_; 86 87 Rex::Commands::profiler()->start("direct_exec: $exec"); 88 89 my $class_name = ref $self; 90 91 Rex::Logger::debug("$class_name/executing: $exec"); 92 my ( $out, $err ) = $self->_exec( $exec, $option ); 93 94 Rex::Commands::profiler()->end("direct_exec: $exec"); 95 96 Rex::Logger::debug($out) if ($out); 97 if ($err) { 98 Rex::Logger::debug("========= ERR ============"); 99 Rex::Logger::debug($err); 100 Rex::Logger::debug("========= ERR ============"); 101 } 102 103 if (wantarray) { return ( $out, $err ); } 104 105 return $out; 106} 107 108sub _exec { 109 my ($self) = @_; 110 my $class_name = ref $self; 111 die("_exec method must be overwritten by class ($class_name)."); 112} 113 114sub shell { 115 my ($self) = @_; 116 117 Rex::Logger::debug("Detecting shell..."); 118 119 my $cache = Rex::get_cache(); 120 if ( $cache->valid("shell") ) { 121 Rex::Logger::debug( "Found shell in cache: " . $cache->get("shell") ); 122 return Rex::Interface::Shell->create( $cache->get("shell") ); 123 } 124 125 my %shells = Rex::Interface::Shell->get_shell_provider; 126 for my $shell ( keys %shells ) { 127 Rex::Logger::debug( "Searching for shell: " . $shell ); 128 $shells{$shell}->require; 129 if ( $shells{$shell}->detect($self) ) { 130 Rex::Logger::debug( "Found shell and using: " . $shell ); 131 $cache->set( "shell", $shell ); 132 return Rex::Interface::Shell->create($shell); 133 } 134 } 135 136 return Rex::Interface::Shell->create("sh"); 137} 138 1391; 140