一直工作到第56行,我想知道我是否正确使用mtime,我以前认为字符串。时光网定义了它。我也不确定是哪个mtime导致了错误,下面是第56行:
如果File.stat (local_file)。mtime> Time.at(rstat.mtime)
这是当我运行下面的代码时得到的错误:
box.ru:56:in `block (3 levels) in <main>': undefined method `mtime' for #<Net::SFTP::Request:0x007fa2799d41d0> (NoMethodError)
rstat = sftp.stat(remote_file)所以第二个mtime也应该被定义,除非remote_file配置错误。谢谢你的关注!
#!/usr/bin/env ruby
require 'rubygems'
require 'net/ssh'
require 'net/sftp'
require 'highline/import'
require 'find'
host = 'server'
local_path = '/Users/awesome1/Development/box'
remote_path = '/home/awesome2/box'
def sanitize_string(string_name)
string_name.gsub(/[^w.-]/,"_")
end
puts "box username:"
user0 = gets.chomp
user = sanitize_string(user0)
pass0 = ask("Enter password for #{user}: ") { |q| q.echo = false }
pass = sanitize_string(pass0)
puts 'connecting to box...'
Net::SSH.start( host, user, :password => pass ) do|ssh|
result = ssh.exec!("cd #{remote_path} && ls")
puts result
ssh.sftp.connect do |sftp|
puts 'Checking for files which need updating'
Find.find(local_path) do |local_file|
next if File.stat(local_file).directory?
remote_file = remote_path + local_file.sub(local_path, '')
begin
remote_dir = File.dirname(remote_file)
sftp.stat(remote_dir)
rescue Net::SFTP::Operations::StatusException => e
raise unless e.code == 2
sftp.mkdir(remote_dir, :mode => dir_perm)
end
begin
rstat = sftp.stat(remote_file)
rescue Net::SFTP::Operations::StatusException => e
raise unless e.code == 2
sftp.put_file(local_file, remote_file)
sftp.setstat(remote_file, :permissions => file_perm)
next
end
if File.stat(local_file).mtime > Time.at(rstat.mtime)
puts "Copying #{local_file} to #{remote_file}"
ssh.sftp.upload(local_file, remote_file)
end
end
end
end
1)除非你的代码正确缩进,否则不要在stack overflow或任何其他计算机编程论坛上发帖。
if File.stat(local_file).mtime > Time.at(rstat.mtime)
这是当我运行下面的代码时得到的错误:
box.ru:56:in block (3 levels) in <main>': undefined method mtime' for <Net::SFTP::Request:0x007fa2799d41d0> (NoMethodError)
2)错误信息暗示rstat是Net::SFTP::Request
类型的对象,如果您查看这里的NET::SFTP
文档:
你会发现mtime()不是Net::SFTP::Request
类的实例方法,也就是说你不能在Net::SFTP::Request
对象上调用mtime()。
:
ssh.sftp.connect do |sftp|
给sftp分配了一个NET::SFTP::Session
类型的对象,所以sftp.stat()必须返回一个Net::SFTP::Request
类型的对象。如果你看一下NET::SFTP::Session#stat()
的文档,他们会让你去看lstat()文档,如果你点击lstat()的链接,lstat()文档说:
方法立即返回一个Request对象。
这个类真的只命名为"Request"吗?点击"请求"链接,在页面顶部你会看到:
Net::SFTP::Request
…并且没有为该类列出名为mtime()的方法。也许mtime()方法包含在某些父类或包含在某处的模块中?父类被列为Object(就在它说Net::SFTP::Request
的下面),Net::SFTP::Request
有一个名为Constants::PacketTypes
的包含模块——但是在Object或Constants::PacketTypes
中都没有mtime()方法。
出于某种原因,你似乎认为sftp.stat(remote_file)
返回一个File对象——它不是;sftp.stat()返回一个Net::SFTP::Request
对象。然而,如果你在调用stat()时指定了一个块(参见lstat()文档),那么该块将被传递一个Net::SFTP::Response对象,并且根据lstat()文档:
响应的:attrs属性将包含Attributes实例适合协议版本(参见Protocol::V01::Attributes、Protocol::V04::Attributes协议::V06::属性).
检查Protocol::V06::Attributes的文档显示响应中有一个:mtime属性,并且:
上述所有属性都公开为方法(尽管不是全部)将使用来自服务器的非nil值设置)。
回到lstat()文档,再看一下这个例子,你会发现你做了这样的事情:
request = sftp.stat(remote_file) do |response|
raise "fail!" unless response.ok?
remote_file_mtime = response[:attrs].mtime
end
request.wait