Module: Cfruby::Exec

Defined in:
lib/libcfruby/exec.rb

Class Method Summary collapse

Class Method Details

.exec(command, user = nil) ⇒ Object

Runs the given command as a forked process, returns stdout and stderr as separate Arrays of output lines. If user is given su will be used to run the command as the given user. FIXME - should use native ruby user switching if possible



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/libcfruby/exec.rb', line 48

def Exec::exec(command, user=nil)
	
	output = Array.new()
	erroroutput = Array.new()
	
	# the following code is a touch hackish because select returns readable
	# on streams that are at EOF, so we have to check for available input
	# as well as for EOF each time through to avoid getting a bunch of
	# blank entry lines.
	attemptmessage = "run \"#{command}\""
	if(user)
		attemptmessage += " as user '#{user}'"
	end
	Cfruby.controller.attempt(attemptmessage, 'unknown', 'exec') {
		if user != nil
			command = "su #{user} -c #{shellescape(command)}"
		end
		Cfruby.controller.inform('debug', "Running '#{command}'")
		stdin, stdout, stderr = Open3.popen3(command)
		reading = true
		while(!stdout.eof? or !stderr.eof?)
			ready = select([stdout], nil, nil, 0)
			ready[0].each() { |istream|
				line = istream.gets()
				if(line != nil)
					output << line
				end
			}
		
			ready = select([stderr], nil, nil, 0)
			if(ready != nil)
				ready[0].each() { |istream|
					line = istream.gets()
					if(line != nil)
						erroroutput << line
					end
				}
			end
		end
	}

	return(Array.[](output, erroroutput))			
end

.shellescape(argument) ⇒ Object

Escapes argument for passing to a shell by surrounding it in single quotes and escaping any internal single quotes



19
20
21
# File 'lib/libcfruby/exec.rb', line 19

def Exec::shellescape(argument)
	argument.gsub(/([\\\t\| &`<>)('"])/) { |s| '\\' << s }
end

.shellexec(command, *args) ⇒ Object

Runs the given command in a shell, escaping each argument in args. Returns the output of the command run



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/libcfruby/exec.rb', line 26

def Exec::shellexec(command, *args)
	argarray = Array.new()
	if(args.length == 1 and args[0].kind_of?(Array))
	  args = args[0]
  end
	args.each() { |argument|
		argarray << "#{shellescape(argument)}"
	}
	
	output = nil
	Cfruby.controller.attempt("run \"#{command.gsub(/ /, "\\ ")} #{argarray.join(' ')}\" in a shell", 'unknown', 'exec') {
		output = `#{shellescape(command.gsub(/ /, "\\ "))} #{argarray.join(' ')}`
	}
				
	return(output)
end