Ruby Open3.popen3模拟用户输入

Ruby Open3.popen3模拟用户输入,ruby,bash,sinatra,popen3,Ruby,Bash,Sinatra,Popen3,我正在尝试运行需要用户输入的bash脚本(@command),并尝试使用以下代码为该脚本输入提供信息: Open3.popen3(@command) do |stdin, stdout, stderr| stdin.write("y") stdout.gets end Open3.popen3(@command)do | stdin、stdout、stderr| 标准写入(“y”) stdout.get 结束 下面是脚本的想法: exec sudo su -c "some command

我正在尝试运行需要用户输入的bash脚本(
@command
),并尝试使用以下代码为该脚本输入提供信息:

Open3.popen3(@command) do |stdin, stdout, stderr| stdin.write("y") stdout.gets end Open3.popen3(@command)do | stdin、stdout、stderr| 标准写入(“y”) stdout.get 结束 下面是脚本的想法:

exec sudo su -c "some command" $username exec sudo su-c“some command”$username 如果有人能告诉我我做错了什么,或者对如何以不同的方式实现这一点有任何建议,我将不胜感激


另外,我可以像这样运行脚本:

@output = `#{@command}` @输出=`{@command}` 在本例中,我可以在运行我的应用程序的控制台中看到脚本输出的内容。如果有任何方法可以将输入输入输入到该位置,那么该方法也会起作用。

这里有我的解决方案:

Open3.popen3(@command)do | stdin、stdout、stderr| stdin.puts“y\r\n” stdout.each|u line{| line | put line} 标准关闭 结束
如果您的代码需要在STDIN上输入,则需要在发送输入后关闭STDIN,否则它可能会挂起等待更多输入。仅仅发送带有行结尾的行通常是不够的,必须关闭流,正如您提到的答案所述。如果子进程试图向流写入大量数据,忽略
stderr
是致命的。如果超过管道缓冲区的大小,操作将挂起超级进程。请参阅的手册页。您可以使用
Open3.popen2e
Open3.capture*
来避免这种情况。如果
@命令是
cat
,则需要在从stdout读取之前关闭
stdin
。否则,
cat
将继续等待输入,而
stdout的读取将挂起。经验法则是:尽早关闭
stdin
,以便让您的子流程知道不会有更多的数据出现。更好的是,使用标准包装器:
Open3.capture2*
。 Open3.popen3(@command) do |stdin, stdout, stderr| stdin.puts "y\r\n" stdout.each_line { |line| puts line } stdin.close end
out_err, status = Open3.capture2e(@command, :stdin_data => "y\r\n")
print out_err