我有一个小红宝石脚本,它的作用是mysql
导入方式:mysql -u <user> -p<pass> -h <host> <db> < file.sql
,但利用Open3.popen3
这样做。这就是我到目前为止所拥有的:
mysqlimp = "mysql -u #{mysqllocal['user']} "
mysqlimp << "-h #{mysqllocal['host']} "
mysqlimp << "-p#{mysqllocal['pass']} "
mysqlimp << "#{mysqllocal['db']}"
Open3.popen3(mysqlimp) do |stdin, stdout, stderr, wthr|
stdin.write "DROP DATABASE IF EXISTS #{mysqllocal['db']};\n"
stdin.write "CREATE DATABASE #{mysqllocal['db']};\n"
stdin.write "USE #{mysqllocal['db']};\n"
stdin.write mysqldump #a string containing the database data
stdin.close
stdout.each_line { |line| puts line }
stdout.close
stderr.each_line { |line| puts line }
stderr.close
end
这实际上是在做这项工作,但有一件事困扰着我,与我想看到的输出有关。
如果我将第一行更改为:
mysqlimp = "mysql -v -u #{mysqllocal['user']} " #note the -v
那么整个脚本就会永远挂起。
我猜,发生这种情况是因为读流和写流互相阻塞,而且我还猜想stdout
需要定期冲洗,以便stdin
将会继续被消耗。换句话说,只要缓冲区stdout
已满,该过程将等待直到其被刷新,但由于这是首先在最底部完成的,所以这种情况永远不会发生。
我希望有人能验证我的理论?我怎样才能编写可以打印出所有内容的代码stdout
并将所有内容写入stdin
还有?
提前致谢!
- 由于您只写入标准输出,因此您可以简单地使用
Open3#popen2e
这巩固了stdout
and stderr
到单个流中。
- 要将换行符终止的字符串写入流,您可以使用
puts
就像你会的那样$stdout
在一个简单的 hello world 程序中。
- 你必须使用
waith_thread.join
or wait_thread.value
等待子进程终止。
- 无论如何,如果您想立即查看结果,则必须启动一个单独的线程来从流中读取数据。
Example:
require 'open3'
cmd = 'sh'
Open3.popen2e(cmd) do |stdin, stdout_stderr, wait_thread|
Thread.new do
stdout_stderr.each {|l| puts l }
end
stdin.puts 'ls'
stdin.close
wait_thread.value
end
您的代码已修复:
require 'open3'
mysqldump = # ...
mysqlimp = "mysql -u #{mysqllocal['user']} "
mysqlimp << "-h #{mysqllocal['host']} "
mysqlimp << "-p#{mysqllocal['pass']} "
mysqlimp << "#{mysqllocal['db']}"
Open3.popen2e(mysqlimp) do |stdin, stdout_stderr, wait_thread|
Thread.new do
stdout_stderr.each {|l| puts l }
end
stdin.puts "DROP DATABASE IF EXISTS #{mysqllocal['db']};"
stdin.puts "CREATE DATABASE #{mysqllocal['db']};"
stdin.puts "USE #{mysqllocal['db']};"
stdin.close
wait_thread.value
end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)