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