Ruby (Errno::EACCES) on File.delete

2019-05-21 06:00发布

问题:

I am trying to delete some XML files after I have finished using them and one of them is giving me this error:

'delete': Permission denied - monthly-builds.xml (Errno::EACCES)

Ruby is claiming that the file is write protected but I set the permissions before I try to delete it.

This is what I am trying to do:

#collect the xml files from the current directory
filenames = Dir.glob("*.xml")

#do stuff to the XML files
finalXML = process_xml_files( filenames )

#clean up directory
filenames.each do |filename|
        File.chmod(777, filename) # Full permissions
        File.delete(filename)
end

Any ideas?

回答1:

This:

File.chmod(777, filename)

doesn't do what you think it does. From the fine manual:

Changes permission bits on the named file(s) to the bit pattern represented by mode_int.

Emphasis mine. File modes are generally specified in octal as that nicely separates the bits into the three Unix permission groups (owner, group, other):

File.chmod(0777, filename)

So you're not actually setting the file to full access, you're setting the permission bits to 01411 which comes out like this:

-r----x--t

rather than the

-rwxrwxrwx

that you're expecting. Notice that your (decimal) 777 permission bitmap has removed write permission.

Also, deleting a file requires write access to the directory that the file is in (on Unixish systems at least) so check the permissions on the directory.

And finally, you might want to check the return value from File.chmod:

[...] Returns the number of files processed.

Just because you call doesn't mean that it will succeed.



回答2:

You may not have access to run chmod. You must own the file to change its permissions.

The file may also be locked by nature of being open in another application. If you're viewing the file in, say, a text editor, you might not be able to delete it.



回答3:

In my case it was because the file I had been trying to delete--kindle .sdr record--was directory, not file. I need to use this instead:

FileUtils.rm_rf(dirname)