jblooze jblooze - 2 months ago 11
Ruby Question

Reading unix file permissions with Ruby

new to Ruby and I've been stuck on this issue for days. I have an array of directories in which I would like to get only the 3-4 digit file permissions bit for all files/directories underneath it (0744).

The problem appears to be the File::Stat class is throwing errors converting the files into an integer. My end goal is to be able to grab the output of the file permission and compare whether the user has less permissions than the 'group' or 'other' and let me know the file (example: 0477) See this link for context: STIG Viewer

Any insight or documentation into this issue would be of great help. Here is initial code to break down and convert the files:

%w(/etc /bin /usr/bin /usr/lbin /usr/usb /sbin /usr/sbin).each do |dir|
Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).each do |c| # include hidden files
m = File.stat("#{c}").world_readable?
sprintf("%o", m)
end
end


And here is my error:

jtest.rb:4:in `sprintf': can't convert File::Stat into Integer (TypeError)
from jtest.rb:4
from jtest.rb:2:in `each'
from jtest.rb:2
from jtest.rb:1:in `each'
from jtest.rb:1

Answer

Does this not give you what you want?

File.stat("#{c}").mode.to_s(8)

Note that .mode is giving you the file permissions as in integer, I think you are just getting confused because the integer representation is base 10, whereas the permissions as you would see them in a console are displayed as base 8.

This should be close to what you want:

%w(/etc /bin /usr/bin /usr/lbin /usr/usb /sbin /usr/sbin).each do |dir|
  Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).each do |c| # include hidden files
    unless File.symlink?(c)
      puts c + " - " + File.stat(c).mode.to_s(8)
    end
  end
end