There are several ways to execute a shell command from your Ruby script. They give you the output and exit code which is often enough. But what if you need more than that? Recently I needed to run the command that prompted for a password. Here’s my simple solution to this – you give the command as usual and then a Hash of matchers-responses. Every line in STDOUT will be analyzed and if it matches any of these guys, the response will be sent to the STDIN. As simple as that:
require'open3'defsystem_with_prompt(cmd,responses={})buffer=[]Open3.popen3(cmd)do|stdin,stdout,stderr|whileline=stdout.gets# Find the responseresponses.eachdo|k,v|match=casewhenk.is_a?(Regexp)k=~lineelsek.to_s==lineend# Respond if foundifmatchv=v.callifv.is_a?(Proc)stdin.putsv.to_sendendbuffer<<lineendendbuffer.joinend# - you get your output as usual# - you can feed many prompt-response pairs in hash# - prompt matcher can either be a string or a regex# - response can be either a string or a lambda / Proc returning the resultoutput=system_with_prompt("command_with_password arg1", /password:/i=>lambda{Time.now.to_s},'Another Filed'=>'...')putsoutput