Ruby 和 Net::SFTP:为什么我不能将它移到一个单独的函数中?
Ruby and Net::SFTP: why can't I move this to a separate function?
编写一个函数,通过 SFTP 检查服务器上是否存在文件。
我已经编写了一个有效的函数 sftp_file_exists_1?
。现在我想把这个函数拆分成两个函数,令我惊讶的是,这不起作用。
require "net/sftp"
def sftp_file_exists_1?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
sftp.stat(filename) do |response|
return response.ok?
end
end
end
def sftp_stat_ok?(sftp, filename)
sftp.stat(filename) do |response|
return response.ok?
end
end
def sftp_file_exists_2?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
return sftp_stat_ok?(sftp, filename)
end
end
p sftp_file_exists_1?("localhost", "user", "repos")
p sftp_file_exists_2?("localhost", "user", "repos")
我预计:
true
true
因为文件 repos
实际上存在于服务器上。但是,我得到(缩写):
true
#<Net::SFTP::Request:0x000055f3b56732d0 @callback=#<Proc:0x000055f3b5673280@./test.rb:14>, ...
附录:有效:
def sftp_stat_ok?(sftp, filename)
begin
sftp.stat!(filename)
rescue Net::SFTP::StatusException
return false
end
return true
end
有趣的问题。
老派调试
让我们添加一些 puts
看看会发生什么:
require "net/sftp"
def sftp_file_exists_1?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
puts " BEFORE STAT"
sftp.stat(filename) do |response|
puts " REQUEST FINISHED"
return response.ok?
end
puts " AFTER STAT"
end
puts " NOT EXECUTED"
end
def sftp_stat_ok?(sftp, filename)
request = sftp.stat(filename) do |response|
puts " REQUEST FINISHED"
return response.ok?
end
puts " REQUEST SENT"
request
end
def sftp_file_exists_2?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
puts " CALL STAT_OK?"
return sftp_stat_ok?(sftp, filename)
end
puts " NOT EXECUTED"
end
sftp_file_exists_1?
输出:
BEFORE STAT
AFTER STAT
REQUEST FINISHED
true
虽然 sftp_file_exists_2?
输出:
CALL STAT_OK?
REQUEST SENT
#<Net::SFTP::Request:0x0000000001db2558>
" REQUEST FINISHED"
没有出现。
异步逻辑
您传递给 stat
is a callback 的区块。它仅在服务器响应时被调用。要确保块在 sftp_stat_ok?
returns 之前执行,您需要等待请求完成:
def sftp_stat_ok?(sftp, filename)
request = sftp.stat(filename) do |response|
return response.ok?
end
request.wait
end
def sftp_file_exists_2?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
return sftp_stat_ok?(sftp, filename)
end
end
第一个版本不需要它,因为 start
:
If a block is given, it will be passed to the SFTP session and will be
called once the SFTP session is fully open and initialized. When the
block terminates, the new SSH session will automatically be closed.
编写一个函数,通过 SFTP 检查服务器上是否存在文件。
我已经编写了一个有效的函数 sftp_file_exists_1?
。现在我想把这个函数拆分成两个函数,令我惊讶的是,这不起作用。
require "net/sftp"
def sftp_file_exists_1?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
sftp.stat(filename) do |response|
return response.ok?
end
end
end
def sftp_stat_ok?(sftp, filename)
sftp.stat(filename) do |response|
return response.ok?
end
end
def sftp_file_exists_2?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
return sftp_stat_ok?(sftp, filename)
end
end
p sftp_file_exists_1?("localhost", "user", "repos")
p sftp_file_exists_2?("localhost", "user", "repos")
我预计:
true
true
因为文件 repos
实际上存在于服务器上。但是,我得到(缩写):
true
#<Net::SFTP::Request:0x000055f3b56732d0 @callback=#<Proc:0x000055f3b5673280@./test.rb:14>, ...
附录:有效:
def sftp_stat_ok?(sftp, filename)
begin
sftp.stat!(filename)
rescue Net::SFTP::StatusException
return false
end
return true
end
有趣的问题。
老派调试
让我们添加一些 puts
看看会发生什么:
require "net/sftp"
def sftp_file_exists_1?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
puts " BEFORE STAT"
sftp.stat(filename) do |response|
puts " REQUEST FINISHED"
return response.ok?
end
puts " AFTER STAT"
end
puts " NOT EXECUTED"
end
def sftp_stat_ok?(sftp, filename)
request = sftp.stat(filename) do |response|
puts " REQUEST FINISHED"
return response.ok?
end
puts " REQUEST SENT"
request
end
def sftp_file_exists_2?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
puts " CALL STAT_OK?"
return sftp_stat_ok?(sftp, filename)
end
puts " NOT EXECUTED"
end
sftp_file_exists_1?
输出:
BEFORE STAT
AFTER STAT
REQUEST FINISHED
true
虽然 sftp_file_exists_2?
输出:
CALL STAT_OK?
REQUEST SENT
#<Net::SFTP::Request:0x0000000001db2558>
" REQUEST FINISHED"
没有出现。
异步逻辑
您传递给 stat
is a callback 的区块。它仅在服务器响应时被调用。要确保块在 sftp_stat_ok?
returns 之前执行,您需要等待请求完成:
def sftp_stat_ok?(sftp, filename)
request = sftp.stat(filename) do |response|
return response.ok?
end
request.wait
end
def sftp_file_exists_2?(host, user, filename)
Net::SFTP.start(host, user, verify_host_key: :always) do |sftp|
return sftp_stat_ok?(sftp, filename)
end
end
第一个版本不需要它,因为 start
:
If a block is given, it will be passed to the SFTP session and will be called once the SFTP session is fully open and initialized. When the block terminates, the new SSH session will automatically be closed.