chmodding and Ruby

Recently, I switched from a Powerbook to a Macbook, and to copy my files from one to the other, I used a pen drive. Since my pen drive has a FAT file system, it treats everything as being executable. This, however, is not the case on a UNIX-like file system like OS X. In order to save myself the hassle of manually chmodding thousands of files, I wrote this Ruby script:

Ruby

#!/usr/bin/env ruby
require 'find'
require 'fileutils'

# Append to/remove from this list as necessary
Plain = ['php', 'txt', 'jpg', 'jpeg', 'gif', 'png', 'html', 'pdf', 'css', 'mp3', 'zip', 'tar.gz', 'tar', 'htm', 'psd', 'ai', 'ptg', 'cgi.pl', 'sphp', 'svn-base', 'default'].collect do |ext|
    ".#{ext}"
end.freeze

# Append to/remove from this list as necessary
Executable = ['pl', 'rb', 'cgi', 'sh'].collect do |ext|
    ".#{ext}"
end.freeze
$num_chmodded = 0

def chmod_and_puts( cmd )
    puts cmd
    system cmd
    $num_chmodded += 1
end

def chmodder( start_dir )
    num_skipped = 0
    num_plain = 0
    num_executable = 0
   
    Find.find( start_dir ) do |path|
        unless File.symlink?( path )
            if FileTest.file? path
                if is_plain? path
                    chmod_and_puts "chmod 644 \"#{path}\""
                    num_plain += 1
                elsif is_executable? path
                    chmod_and_puts "chmod 755 \"#{path}\""
                    num_executable += 1
                else
                    num_skipped += 1
                end
            elsif File.directory? path
                chmod_and_puts "chmod 755 \"#{path}\""
                num_executable += 1
            else
                num_skipped += 1
            end
        else
            num_skipped += 1
        end
    end
   
    puts "----------------------------------------------"
    puts "Chmodded #{$num_chmodded} total:"
    puts "\tExecutable: #{num_executable}"
    puts "\tPlain: #{num_plain}"
    puts "Skipped #{num_skipped} files/directories/symlinks"
end

def get_extension( path )
    File.extname( path ).downcase
end

def is_executable?( path )
    extension = get_extension( path )
   
    if Executable.include? extension
        true
    else
        false
    end
end

def is_plain?( path )
    extension = get_extension( path )
   
    if Plain.include? extension
        true
    else
        false
    end
end

chmodder( '.' )

This goes through all the files and directories within the directory from which you run the script and chmods non-executable files to 644 (read+write on User, read on Group and Other) and executable files to 755 (read+write+execute on User, read+execute on Group and Other). If you're unfamiliar with the chmod command, you might want to read my beginning Linux guide.

This entry was posted in Linux, OS X, Programming and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

2 Comments

  1. Posted 22 January 2010 at 8:50 PM | Permalink

    You realize that:
    if Executable.include? extension
    true
    else
    false
    end

    is equivalent to simply:
    Executable.include(extension)

    right?

    :)

  2. Posted 22 January 2010 at 8:51 PM | Permalink

    ugh, somehow the ‘?’ (question-mark) after the include was excluded from my post, no idea why :(

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>