目標:我正在用ruby編寫一個工作流命令行程序,它依次執行UNIX shell上的其他程序,其中一些需要用戶輸入輸入。Runy Open3.popen3從命令行輸入子進程
問題:雖然我可以成功Nick Charlton處理stdout
和stderr
感謝這個有用blog post,不過,我被困在捕捉用戶輸入,並將其傳遞到子過程通過命令行。的代碼如下:
方法
module CMD
def run(cmd, &block)
Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
Thread.new do # STDOUT
until (line = stdout.gets).nil? do
yield nil, line, nil, thread if block_given?
end
end
Thread.new do # STDERR
until (line = stderr.gets).nil? do
yield nil, nil, line, thread if block_given?
end
end
Thread.new do # STDIN
# ????? How to handle
end
thread.join
end
end
end
調用方法
此示例調用外殼命令units
它提示用戶輸入的測量單位,然後提示一個單位轉換爲。這是怎麼會看在外殼
> units
586 units, 56 prefixes # stdout
You have: 1 litre # user input
You want: gallons # user input
* 0.26417205 # stdout
/3.7854118 # stdout
當我運行這個從我的節目,我希望能夠以完全相同的方式與它進行交互。
unix_cmd = 'units'
run unix_cmd do | stdin, stdout, stderr, thread|
puts "stdout #{stdout.strip}" if stdout
puts "stderr #{stderr.strip}" if stderr
# I'm unsure how I would allow the user to
# interact with STDIN here?
end
注:調用run
方法這種方法允許用戶可以解析輸出,控制流程,並添加自定義日誌記錄。
從我收集到的有關標準輸入,下面的代碼片段是接近我是來了解如何處理STDIN,明顯有在我所知一些差距,因爲我仍然不確定如何整合這個放到我上面的run
方法中,並將輸入傳遞給子進程。
# STDIN: Constant declared in ruby
# stdin: Parameter declared in Open3.popen3
Thread.new do
# Read each line from the console
STDIN.each_line do |line|
puts "STDIN: #{line}" # print captured input
stdin.write line # write input into stdin
stdin.sync # sync the input into the sub process
break if line == "\n"
end
end
摘要:我希望瞭解如何從通過Open3.popen3
方法的命令行處理用戶輸入,這樣我可以允許用戶將數據輸入到從我的程序稱爲子指令的各種序列。
我也很想知道如何做到這一點 –