我有一个小的ruby脚本,该脚本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
并stderr
成一个单一的数据流。puts
像$stdout
在简单的hello world程序中一样使用。waith_thread.join
或wait_thread.value
等到子进程终止。例:
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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句