From: Robert Klemme Date: 2010-06-02T00:44:12+09:00 Subject: Re: looping through array elements (noob question) 2010/6/1 Nate St.germain : > please bear with me on this. i'm blundering my way through learning > ruby. > > i have a script intended to run on os x to restore local admin rights to > users who've had the rights removed by another script. it's sort of a > fallback measure. i'm using this as an opportunity to learn ruby in the > process. > > the newest version of the removal script (bash) will add a plain text > file in /Library/Receipts containing the account short names on which it > just operated. i want the restore script to be flexible enough to either > read the list from the file if it exists or get the users from scratch > using the "/usr/sbin/jamf listUser" command (part of the Casper admin > suite), which outputs xml, unfortunately. at some point, i'll probably > switch to another method to avoid having to resort to regex matches on > the xml tags. > > regardless, the issue is the getUsers() method works fine on its own but > then give me the following output when run from the script (below): > > sam > norton > mary > Restoring admin rights for     sam > Restoring admin rights for     norton > Restoring admin rights for     mary > > so in the actual script, the names are returned once correctly, then > again with the xml tags and tabs intact. i'm not sure what i'm missing > here. > > it's probably something obvious, and i'm sure this script can be written > more concisely. i appreciate any pointers you have. note, the actual > admin rights granting lines are commented below for testing. > > > === script === > > #!/usr/bin/env ruby > # restore rights to local users who've recently had them removed. > # 5/25/10, nate@tsp > # 6/1/10, updated > > # set system variable > # chops out the second digit in the version number, which is the only > differentiating factor here > def getos() >  system=`/usr/bin/sw_vers > -productVersion`.chomp.split(".").slice(1).to_i >  if system==4 then >    return "tiger" >  else >      return "leo" >  end > end > > # cheating by using the jamf binary. > def getUsers() >  userlist=`/usr/sbin/jamf listUsers`.to_a >  users=userlist.grep /\  users.each { |user| puts user.split(/<[^>]*[^>]*>/)[1] } The line above produces the output of the short names - and then it returns "users" *unmodified*. This means that the array returned from getUsers() still has all the XML tags in there. You can replace that line with: users.map { |user| user.split(/<[^>]*[^>]*>/)[1] } Or, with an alternative approach def get_users users = [] `/usr/sbin/jamf listUsers`.scan(/(.*?)/) { users << $1 } users end Or even use an XML tool (e.g. REXML) to extract values of tags if the input is valid XML. Note: conventionally we use CamelCase only for ClassNames and not for method_names. > end > > # method to read admins from a text file from a removal run > # this may not be necessary if included in the restoreAdmin methods > def readAdmins() >  receipt=File.open('/Library/Receipts/org.company.removedadmins', 'r') >  return receipt.readlines > end > > # use dseditgroup for 10.[5-6] clients > def restoreAdmin5() >  if File.exist?('/Library/Receipts/org.company.removedadmins') then >    users=readAdmins >    users.each do |u| >    puts "Restoring admin rights for #{u}" >  #  %x(/usr/sbin/dseditgroup -o edit -a  #{u} -t user admin) >    end >  else >    users=getUsers >    users.each do |u| >    puts "Restoring admin rights for #{u}" >  #  %x(/usr/sbin/dseditgroup -o edit -a  #{u} -t user admin) >    end >  end > end > > # use nicl for 10.4 clients > def restoreAdmin4() >  if File.exist?('/Library/Receipts/org.company.removedadmins') then >    users=readAdmins >    users.each do |u| >      puts "Restoring admin rights for #{u}" >  #    %x(nicl -raw /var/db/netinfo/local.nidb -append /groups/admin > users #{u}) >  end >  else >    users=getUsers >    users.each do |u| >    puts "Restoring admin rights for #{u}" >  #  %x(nicl -raw /var/db/netinfo/local.nidb -append /groups/admin users > #{u}) >    end >  end > end > > # test the os with the getos() method and proceed accordingly based on > platform > result = case getos() >  when "tiger" then >    restoreAdmin4 >  when "leo" then >    restoreAdmin5 >  else puts "no version specified. stopping..." >  end Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/