def sh(command,options={},&block)
      sh_logger.debug("Executing '#{command}'")

      stdout,stderr,status = execution_strategy.run_command(command)
      process_status = Methadone::ProcessStatus.new(status,options[:expected])

      sh_logger.warn("stderr output of '#{command}': #{stderr}") unless stderr.strip.length == 0

      if process_status.success?
        sh_logger.debug("stdout output of '#{command}': #{stdout}") unless stdout.strip.length == 0
        call_block(block,stdout,stderr,process_status.exitstatus) unless block.nil?
      else
        sh_logger.info("stdout output of '#{command}': #{stdout}") unless stdout.strip.length == 0
        sh_logger.warn("Error running '#{command}'")
      end

      process_status.exitstatus
    rescue *exception_meaning_command_not_found => ex
      sh_logger.error("Error running '#{command}': #{ex.message}")
      127
    end
def sh(command,options={},&block)
      sh_logger.debug("Executing '#{command}'")

      stdout,stderr,status = execution_strategy.run_command(command)
      process_status = Methadone::ProcessStatus.new(status,options[:expected])

      sh_logger.warn("stderr output of '#{command}': #{stderr}") unless stderr.strip.length == 0

      if process_status.success?
        sh_logger.debug("stdout output of '#{command}': #{stdout}") unless stdout.strip.length == 0
        call_block(block,stdout,stderr,process_status.exitstatus) unless block.nil?
      else
        sh_logger.info("stdout output of '#{command}': #{stdout}") unless stdout.strip.length == 0
        sh_logger.warn("Error running '#{command}'")
      end

      process_status.exitstatus
    rescue *exception_meaning_command_not_found => ex
      sh_logger.error("Error running '#{command}': #{ex.message}")
      127
    end
Run a shell command, capturing and logging its output.
 If the command completed successfully, it's output is logged at DEBUG.
 If not, its output as logged at INFO.  In either case, its
 error output is logged at WARN.

 command:: the command to run as a String or Array of String.  The String form is simplest, but
           is open to injection.  If you need to execute a command that is assembled from some portion
           of user input, consider using an Array of String.  This form prevents tokenization that occurs
           in the String form.  The first element is the command to execute,
           and the remainder are the arguments. See Methadone::ExecutionStrategy::Base for more info.
 options:: options to control the call. Currently responds to:
           +:expected+:: an Int or Array of Int representing error codes, <b>in addition to 0</b>, that are
                         expected and therefore constitute success.  Useful for commands that don't use
                         exit codes the way you'd like
 block:: if provided, will be called if the command exited nonzero.  The block may take 0, 1, 2, or 3 arguments.
         The arguments provided are the standard output as a string, standard error as a string, and
         the exitstatus as an Int.
         You should be safe to pass in a lambda instead of a block, as long as your
         lambda doesn't take more than three arguments

 Example

     sh "cp foo /tmp"
     sh "ls /tmp" do |stdout|
       # stdout contains the output of ls /tmp
     end
     sh "ls -l /tmp foobar" do |stdout,stderr|
       # ...
     end

 Returns the exit status of the command.  Note that if the command doesn't exist, this returns 127.