Module: ShellHelpers::Run

Extended by:
Run
Included in:
ShellHelpers, Run
Defined in:
lib/shell_helpers/run.rb

Overview

{{{

Defined Under Namespace

Modules: Interrupt

Constant Summary collapse

RunError =
Class.new(StandardError)

Instance Method Summary collapse

Instance Method Details

#output_of(*command) {|stdout, status| ... } ⇒ Object

Only capture output

Yields:

  • (stdout, status)


19
20
21
22
23
# File 'lib/shell_helpers/run.rb', line 19

def output_of(*command)
  stdout,status = Open3.capture2(*command)
  yield stdout, status if block_given?
  return stdout
end

#process_command(*args, **opts) ⇒ Object

get the args, environment and spawning options



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/shell_helpers/run.rb', line 56

def process_command(*args, **opts)
  spawn_opts={}
  if args.last.kind_of?(Hash)
    #we may have no symbol keywords
    *args,spawn_opts=*args
  end
  sudo=opts.delete(:sudo)
  env={}
  if args.first.kind_of?(Hash)
    env,*args=*args
  end
  env.merge!(opts.delete(:env)||{})
  args=args.map.with_index {|arg, i| i == 0 && arg.is_a?(Array) ? arg : arg.to_s} if args.length > 1
  spawn_opts.merge!(opts)
  if sudo
    if args.length > 1
      args.unshift(*Run.sudo_args(sudo)) 
    else
      args="#{Run.sudo_args(sudo).shelljoin} #{args.first}"
    end
  end
  return env, args, spawn_opts
end

#run(*args, output: :capture, error: nil, fail_mode: :error, chomp: false, sudo: false, error_mode: nil, expected: nil, on_success: nil, quiet: nil, **opts) {|status_success, out, err, status| ... } ⇒ Object

Run a command by default capture stdout and status callbacks: yield status.success?, out, err, status if block_given? if status.success? => on_success.call(status, out, err) else error_mode.call(status, out, error) rescue ... => fail_mode.call(e) return status, out, error

Yields:

  • (status_success, out, err, status)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/shell_helpers/run.rb', line 87

def run(*args, output: :capture, error: nil, fail_mode: :error, chomp: false, sudo: false, error_mode: nil, expected: nil, on_success: nil, quiet: nil, **opts)
  env, args, spawn_opts=Run.process_command(*args, sudo: sudo, **opts)

  if args.is_a?(Array)
    if args.length > 1
      launch=args.shelljoin
    else
      launch=args.first #assume it has already been escaped
    end
  else
    launch=args.to_s
  end
  launch+=" 2>/dev/null" if error==:quiet or quiet
  launch+=" >/dev/null" if output==:quiet
  out=err=nil

  begin
    if error==:capture
      out, err, status=Open3.capture3(env, launch, spawn_opts)
    elsif output==:capture
      out, status=Open3.capture2(env, launch, spawn_opts)
    else
      system(env, launch, spawn_opts)
      status=$?
    end
  rescue => e
    status=false
    case fail_mode
    when :error
      raise e
    when :empty
      out=""
    when :nil
      out=nil
    when Proc
      fail_mode.call(e)
    end
  end
  status=ProcessStatus.new(status, expected) if expected
  status_success=status.success? if status.respond_to? :success?
  yield status_success, out, err, status if block_given?
  if status_success
    # this block is called in case of success
    on_success.call(status, out, err) if on_success.is_a?(Proc)
  else # the command failed
    case error_mode
    when :nil
      out=nil
    when :empty
      out=""
    when :error
      raise RunError.new("Error running command '#{launch}': #{status}")
    when Proc
      error_mode.call(status, out, err)
    end
  end
  if chomp and out
    case chomp
    when :line, :lines
      #out is now an array
      out=out.each_line.map {|l| l.chomp}
    else
      out.chomp! 
    end
  end

  # return out, error, status if error
  return status, out, err
end

#run_command(*command) ⇒ Object

the run_* commands here capture all the output



13
14
15
16
# File 'lib/shell_helpers/run.rb', line 13

def run_command(*command)
  #stdout, stderr, status
  return Open3.capture3(*command)
end

#run_lazy(*command) ⇒ Object

wrap the output of the command in an enumerator allows to lazily parse the result



35
36
37
38
39
40
41
# File 'lib/shell_helpers/run.rb', line 35

def run_lazy(*command)
  r=nil
  IO.popen(command) do |f|
    r=f.each_line.lazy
  end
  r
end

#run_simple(*command, **opts, &b) ⇒ Object

a simple wrapper for %x// return the output; the block is called in case of an error eg SH.run_simple("echo foo; false") do p "error" end => returns "foo\n" and prints error



161
162
163
164
165
166
# File 'lib/shell_helpers/run.rb', line 161

def run_simple(*command, **opts, &b)
  # here the block is called in case of error
  opts[:error_mode]=b if b
  _status, out, _error = run(*command, **opts)
  return out
end

#run_success(*command, **opts, &b) ⇒ Object

like run, but only returns status.success?



169
170
171
172
# File 'lib/shell_helpers/run.rb', line 169

def run_success(*command, **opts, &b)
  status, _out, _error = run(*command, **opts, &b)
  status.success?
end

#status_of(*command) {|stdout, stderr, status| ... } ⇒ Object

Yields:

  • (stdout, stderr, status)


25
26
27
28
29
30
31
# File 'lib/shell_helpers/run.rb', line 25

def status_of(*command)
  stdout,stderr,status = run_command(*command)
  yield stdout, stderr, status if block_given?
  return status.success?
  #system(*command)
  #return $?.dup
end

#sudo_args(sudoarg) ⇒ Object

Launching a command handle sudo arguments



46
47
48
49
50
51
52
53
# File 'lib/shell_helpers/run.rb', line 46

def sudo_args(sudoarg)
  if sudoarg.respond_to?(:sudo_loop)
    sudoarg.sudo_loop
  end
  return [] unless sudoarg
  return sudoarg.shellsplit if sudoarg.is_a?(String)
  ["sudo"]
end