简体   繁体   中英

Delete a file using Ruby SFTP `remove` and `remove!`

I am trying to old delete files from an FTP using Ruby net/sftp , but I keep getting an error saying the file does not exist.

:error=>"Net::SFTP::StatusException (2, \"no such file\")"

I can manually delete files when logging in using the same creds, so I know I have permission.

require 'net/sftp'
ftp = Net::SFTP.start(@ftp_url, @ftp_user, :password =>  @ftp_pwd)
ftp.dir.entries('somePath').each do |entry|
    begin
      age_days = (Time.now.to_i - entry.attributes.atime) / 86400

      if(age_days > ftp_max_file_age_days)
        ftp.remove!(entry.name)
      end

    rescue Exception => e
      # log error here
    end
end

I prefer remove! so everything happens synchronously in this case, but I have also tried remove .

I also tried giving it the full path of the file instead of just the entry name (like 'somePath' + entry.name instead of just entry.name ). I was thinking perhaps it was because I needed to change the working directory, which apparently net/sftp does not allow.

Thanks in advance!

Check if entry is a directory if yes then use ftp.rmdir . like below -

require 'net/sftp'
ftp = Net::SFTP.start(@ftp_url, @ftp_user, :password =>  @ftp_pwd)
ftp.dir.entries('somePath').each do |entry|
  begin
    age_days = (Time.now.to_i - entry.attributes.atime) / 86400

    if(age_days > ftp_max_file_age_days)
      if File.directory?(entry.name)
        ftp.rmdir(entry.name) 
      else         
        ftp.remove!(entry.name)
      end
    end

  rescue Exception => e
    # log error here
  end
end

We were eventually able to delete files using the remove method (instead of remove! .) We made a small change to the way we provide the password.

We confirmed that permissions on the FTP did not change, so I think using non_interactive: true may have been the trick.

require 'net/sftp'

def self.delete_report(endpoint, username, password, report_filename)
  SSH_OPTIONS = { non_interactive: true }.freeze
  report_filename_base = File.basename(report_filename, '.*')

  Net::SFTP.start(endpoint, username, SSH_OPTIONS.merge(password: password)) do |sftp|
    sftp.remove(report_filename)
    sftp.remove("#{report_filename_base}.fin")
    sftp.remove("processed/#{report_filename}")
    sftp.remove("processed/#{report_filename_base}.fin")
    sftp.remove("failed/#{report_filename}")
    sftp.remove("failed/#{report_filename_base}.fin")
    sftp.remove("failed/#{report_filename_base}.info")
  end

I still don't fully understand why the same method did not work before, but we're able to delete files in subfolders too, as shown in this example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM