rubyftpsftpdelete-filenet-sftp

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!


Solution

  • 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.