From: Hal Fulton Date: 2004-04-11T15:48:00+09:00 Subject: Just for fun: symbolic chmod I think Ruby's chmod should operate symbolically as the command line version does. To that end, I've been playing around. (Yes, I do have a TV, but nothing is on.) Here's some code. It only implements rwx on the righthand side so far. I test it by calling the OS's chmod, so your mileage may vary. In fact, I'm unsure why the last test case is failing. (I added these more or less randomly.) But given the ugly nature of test12, I'm not really concerned much. If you feel like it: Add, refactor, critique. It's a small thing, but I'd like to see this functionality added into the core if Matz should see fit. Cheers, Hal ############### def sym2oct(init,str) left = {"u" => 0700, "g" => 0070, "o" => 0007, "a" => 0777} right = {"r" => 0444, "w" => 0222, "x" => 0111} reg = /([ugoa]+)([+-=])([rwx]+)/ cmds = str.split(",") perm = init cmds.each do |cmd| match = cmd.match(reg) junk,who,what,how = match.to_a who = who.split(//).inject(num=0) {|num,b| num |= left[b]; num } how = how.split(//).inject(num=0) {|num,b| num |= right[b]; num } mask = who & how case what when "+"; perm = perm | mask when "-"; perm = perm & ~mask when "="; perm = mask end end perm end if $0 == __FILE__ require "test/unit" def try(str) File.unlink("file1") if File.exist?("file1") File.unlink("file2") if File.exist?("file2") File.open("file1","w") { } # Create files File.open("file2","w") { } init = File.stat("file1").mode # Get initial perms (re umask) perm = sym2oct(init,str) File.chmod(perm,"file1") # chmod file1 thru Ruby system("chmod #{str} file2") # chmod file2 thru OS trial = File.stat("file1").mode # and check results actual = File.stat("file2").mode assert_equal(trial.to_s(8),actual.to_s(8)) end class Tester < Test::Unit::TestCase def test01; try("a+w"); end def test02; try("a+rw"); end def test03; try("a-w"); end def test04; try("u+w"); end def test05; try("u-r"); end def test06; try("u-rx"); end def test07; try("g+rx"); end def test08; try("g-rw"); end def test09; try("a+w,g+r,o+x"); end def test10; try("ugo+w,a-w"); end def test11; try("a=rwx"); end def test12; try("g=rw,a+x,o-w"); end end end