class R::Command

A high level interface for executing commands.

Attributes

clearenv[RW]

@!attribute [rw] clearenv

If set, the executed command will not inherit environment variables
from Rub.  Only the values in {#env} will be present in the
environment.

Defaults to false.

@return [true,false] If true don't inherit the environment.
cmd[R]

@!attribute [r] cmd

@return [Array<String>] The command to run.
env[R]

@!attribute [r] env

Control the environment of the spawned process.  Values from this
hash will be added to the processes environment.  If a value is
nil the key will be removed from the processes environment.  These
values are overlaid on the existing environment unless {#clearenv}
is set.

@return [Hash{String=>String,nil}] The environment variables.
mergeouts[RW]

@!attribute [rw] mergeouts

@return [true,false] If true merge {#stdout} into {#stderr}.
status[R]

@!attribute [r] status

Available after {#block} has returned.

@return [Process::Status,nil] The processes exit status.
stderr[R]

@!attribute [r] stdout

@return [String] The output produced by the command.

@!attribute [r] stderr

@return [String] The error output produced by the command.
stdin[RW]

@!attribute [rw] stdin

@return [String] The string to use as input to the command.
stdout[R]

@!attribute [r] stdout

@return [String] The output produced by the command.

@!attribute [r] stderr

@return [String] The error output produced by the command.

Public Class Methods

new(cmd) click to toggle source

Create a new command to run.

@param cmd [Array<String,#to_s>] The command that will be run.

# File lib/rub/r/command.rb, line 74
def initialize(cmd)
        @env = {}
        
        @clearenv = false
        @mergeouts = false
        
        @cmd = cmd.map{|a| a.to_s}
end

Public Instance Methods

block() click to toggle source

Wait for a command to finish.

Block until a currently running process finishes. Behaviour is undefined if the command is not currently running ({#start} has been called since the last {#block}).

After this call returns {#status} will be available.

@return [true,false] Whether the command completed successfully.

# File lib/rub/r/command.rb, line 144
def block
        @stdout = @stdoutr.read
        @stderr = @stderrr.read
        
        #puts "Blocking on #{@pid} #{@cmd.join' '}"
        pid, @status = Process.wait2 @pid
        #puts "Done #{@cmd.join' '}"
        
        @stdoutr.close
        @stderrr.close
        
        success?
end
run() click to toggle source

Run the command and block until completion.

Equivalent to calling {#start} then {#block}.

@return [true,false] Whether the command completed successfully.

# File lib/rub/r/command.rb, line 130
def run
        start
        block
end
start() click to toggle source

Start the command.

Executes the command. The command will run in the background. If you want to wait for the command to complete call {#block}.

@note Calling this command a second time before {#block} returns

produces undefined behaviour.  A {Command} can be run multiple
times but it must finish before being run again.
# File lib/rub/r/command.rb, line 91
def start
        @status = nil

        @stdinr,  @stdinw  = IO.pipe
        @stdoutr, @stdoutw = IO.pipe
        @stderrr, @stderrw = IO.pipe
        
        @stdout = ""
        @stderr = ""
        @status = nil
        
        args = [
                @env,
                *@cmd.map{|a| a.to_s},
                :unsetenv_others=>@clearenv,
                :in =>@stdinr,
                :out=>@stdoutw,
                :err=>(@mergeouts?@stdoutw:@stderrw),
        ]
        
        #p "args: #{args}"
        @pid = spawn(*args)
        
        @stdinr.close
        
        @stdinw.write @stdin
        
        @stdinw.close
        @stdoutw.close
        @stderrw.close
        
        @pid
end
success?() click to toggle source

Check if the command was successful

@return [true,false] true if the command executed successfully

otherwise false.

@note If the command has not been executed or has not completed this

returns false.
# File lib/rub/r/command.rb, line 164
def success?
        !!( @status and @status.exitstatus == 0 )
end