Go Back   The macosxhints Forums > OS X Help Requests > UNIX - General



Reply
 
Thread Tools Rating: Thread Rating: 5 votes, 5.00 average. Display Modes
Old 02-15-2008, 10:38 AM   #1
tlarkin
League Commissioner
 
Join Date: Mar 2003
Location: Bay Area, CA
Posts: 11,351
Script to delete user specific folders

So, I have a policy created that will delete certain folders in a users home directory to delete certain preferences so when an update of the application is pushed out it gets a fresh load of preferences. As of now the script works and it is written to delete the local hidden admin account and the current user that is logged in.

One small problem, in small cases there are perhaps a few user accounts on the machine. All user accounts are mobile so they are both network and local and i need to script so that it pulls up every user account that is in /Users and wipes out these specific folders.

So, how do I code a script to grep or pull up all user accounts and then delete certain user folders? These are tiger clients too, so could or should I use the netinfo database from the command line?

Thoughts and suggestions?

Thanks in advance
tlarkin is offline   Reply With Quote
Old 02-15-2008, 10:47 AM   #2
hayne
Site Admin
 
Join Date: Jan 2002
Location: Montreal
Posts: 32,386
I don't understand the problem.
Why isn't it as simple as looping through (or wildcarding through) all folders under /Users ?
__________________
hayne.net/macosx.html
hayne is offline   Reply With Quote
Old 02-15-2008, 11:05 AM   #3
tlarkin
League Commissioner
 
Join Date: Mar 2003
Location: Bay Area, CA
Posts: 11,351
Um, I am not sure how to properly code it to loop through all the users in the /users directory I guess is the problem hayne.
tlarkin is offline   Reply With Quote
Old 02-15-2008, 12:45 PM   #4
Mikey-San
Hall of Famer
 
Join Date: Jan 2002
Posts: 3,541
This should do the trick. Uncomment line 73 (the rm line) when you're ready to test it out.

Errors the script encounters are logged to the system log via /usr/bin/logger.

Code:
#!/bin/sh

PATH='/bin:/usr/bin'
ls=/bin/ls
rm=/bin/rm
logger=/usr/bin/logger


#############################################################
# Set the internal field separator to the newline character.
# This lets us iterate through each line of a file or
# \n-terminated stdout data. Think of this as a text item
# delimiter.
#############################################################
IFS=$'\n'


# success
noErr=0

# there was an error encountered while removing a directory
errCouldNotRemoveDirectory=1


# folders whose names match the items in the exemptedFolders array will not be deleted.
# add the name of a folder here to exempt it from this script's actions.
declare -a exemptedFolders
exemptedFolders=( "Shared" )

# test to see if an array contains an item. takes two parameters. the first is an array of
# items to search, the second is an item for which to search.
# example usage:
# arrayContainsItem $anArray "$someString"
function arrayContainsItem()
{
	result=1

	array=$1
	item=$2
		
	for each in ${array[*]}
	do
		if [ "$item" == "$each" ]
		then
			result=0
			break
		fi
	done
	
	return $result
}


# get a listing of everything inside /Users
usersDirectoryContents=`$ls /Users`

# iterate over all of the items in /Users
for dir in $usersDirectoryContents
do
	arrayContainsItem $exemptedFolders "$dir"
	exists=$?

	# if this item isn't one of our exempted folders, we want to remove it.
	if [ $exists != 0 ]
	then
		target="/Users/$dir"
		
		# make sure it's a directory; we only want to remove directories.
		if [ -d "$target" ]
		then
			# attempt to remove the directory.
			echo "Removing: $target"
			#$rm -rf "$target"
			rmResult=$?
			
			# if rm didn't exit with 0 status, something went wrong. log it and bail!
			if [ rmResult != 0 ]
			then
				$logger "Error $errCouldNotRemoveDirectory: $target could not be removed. $rm exited with status $rmResult. Bailing."
				exit $errCouldNotRemoveDirectory
			fi
		fi
	fi
done

exit $noErr
__________________
COMPUTER TYPE
SOME SPECIFICATIONS I COPIED FROM THE BOX
STUFF I INSTALLED ALL BY MYSELF
"WITTY QUOTE"

Last edited by Mikey-San; 02-15-2008 at 12:49 PM.
Mikey-San is offline   Reply With Quote
Old 02-15-2008, 12:48 PM   #5
tlarkin
League Commissioner
 
Join Date: Mar 2003
Location: Bay Area, CA
Posts: 11,351
thanks mikey I will try it out, and you didn't have to do that I would have researched it myself. I appreciate it.

Thanks
tlarkin is offline   Reply With Quote
Old 02-15-2008, 01:01 PM   #6
Mikey-San
Hall of Famer
 
Join Date: Jan 2002
Posts: 3,541
No prob. Hopefully, the comments made sense.

Let us know if it works for you or not.
__________________
COMPUTER TYPE
SOME SPECIFICATIONS I COPIED FROM THE BOX
STUFF I INSTALLED ALL BY MYSELF
"WITTY QUOTE"
Mikey-San is offline   Reply With Quote
Old 02-17-2008, 12:22 AM   #7
ghostdog74
Triple-A Player
 
Join Date: May 2007
Posts: 78
that's one good script. However if i get the requirement correct, its just equivalent to something like
Code:
find . -type d ! -name "Shared -exec rm {} \;
except it only exclude one directory.
ghostdog74 is offline   Reply With Quote
Old 02-17-2008, 12:28 AM   #8
Mikey-San
Hall of Famer
 
Join Date: Jan 2002
Posts: 3,541
Yeah, I was just gonna one-liner it, but wanted to give tlarkin more logging opportunities (since he can pepper them anywhere he likes later) and an ability to exempt more directories in the future. It's the "completist sysadmin" response taking over, probably.
__________________
COMPUTER TYPE
SOME SPECIFICATIONS I COPIED FROM THE BOX
STUFF I INSTALLED ALL BY MYSELF
"WITTY QUOTE"
Mikey-San is offline   Reply With Quote
Old 02-19-2008, 08:56 AM   #9
tlarkin
League Commissioner
 
Join Date: Mar 2003
Location: Bay Area, CA
Posts: 11,351
So I was reading through this script, and correct me if I am wrong but if I need to delete these two folders:

~/Library/Application\ Support/Firefox

~/Library/Preferences


in your script I just need to add them to the target value, correct?

This is because if I don't delete these two folders and push out our new firefox package it picks up all the old user preferences in the new vesrion which are no longer correct. Our network changed and since firefox has its own settings I need to push out a new copy of firefox. Which I have done, and I have written a script that deletes those directories. The only problem is the policy is set to run once per a machine, so if someone logs into someone else's laptop and it runs the script will only run on that user, due to my lack of programming knowledge. I could set the policy to run as once per a user, but that would then install firefox many different times on the same machine, which would be a waste, and I could set the scripts as once per a user in the policy but then I have the script running at different times of the software being deployed, and that sounds sloppy.
tlarkin is offline   Reply With Quote
Old 02-19-2008, 12:25 PM   #10
Mikey-San
Hall of Famer
 
Join Date: Jan 2002
Posts: 3,541
The script I posted, as well as the one-liner, delete every folder in /Users except /Users/Shared. Everything. All user folders get rm'ed from the top, which includes their contents. That's what you wanted, right?
__________________
COMPUTER TYPE
SOME SPECIFICATIONS I COPIED FROM THE BOX
STUFF I INSTALLED ALL BY MYSELF
"WITTY QUOTE"
Mikey-San is offline   Reply With Quote
Old 02-19-2008, 12:34 PM   #11
tlarkin
League Commissioner
 
Join Date: Mar 2003
Location: Bay Area, CA
Posts: 11,351
Quote:
Originally Posted by Mikey-San
The script I posted, as well as the one-liner, delete every folder in /Users except /Users/Shared. Everything. All user folders get rm'ed from the top, which includes their contents. That's what you wanted, right?

heh, nope I need to remove specific holders to a home directory, mainly in ~/Library/Preferences and in ~/Library/Application Support.

I was reading through your script and saw that, and I am sorry that i didn't clarify, I just need to delete a few specific folders.

Sorry for the confusion.
tlarkin is offline   Reply With Quote
Old 02-19-2008, 01:03 PM   #12
Mikey-San
Hall of Famer
 
Join Date: Jan 2002
Posts: 3,541
S'ok. Writing a script to delete just a couple of folders whose specific path you know is pretty straightforward. How are you running them? A login hook?
__________________
COMPUTER TYPE
SOME SPECIFICATIONS I COPIED FROM THE BOX
STUFF I INSTALLED ALL BY MYSELF
"WITTY QUOTE"
Mikey-San is offline   Reply With Quote
Old 02-19-2008, 02:02 PM   #13
tlarkin
League Commissioner
 
Join Date: Mar 2003
Location: Bay Area, CA
Posts: 11,351
Quote:
Originally Posted by Mikey-San
S'ok. Writing a script to delete just a couple of folders whose specific path you know is pretty straightforward. How are you running them? A login hook?

Sort of. I am running casper suite at work (which is a nifty product) that has a binary client running via SSH to a casper server which houses network policies I create. The client checks in with the server every 15 minutes or when it can, and checks for current jobs that are queued in its group. it then does a forced pull (not a push from the server there is a difference) from the nearest file share (also configured on the network side) of that policy.

It can be triggered at log in/out, boot, every 15 minutes, or by any of the above.

Then each policy has the options of installing packages, running scripts, updating inventory, reseting passwords, so on and so forth. It's pretty dope actually, and yes I just said dope.

Like for example, I have to push out CS 3 to like 200 laptops with mobile users that run around all over the place. I am not going to push out CS3 over the wireless, that is just retarded, so instead I had my Cisco guy set up a managed 48 port high speed switch to a specific VLAN. Only this certain switch has this VLAN in my whole subnet which I am in charge of. So, I then create a policy to install CS 3 to this specific VLAN, and only to these specific groups. I then have the user come to me, I jack their laptop into the switch and reboot. Upon reboot CS3 automatically installs. It's dope. I don't have to do a thing after that. With the minor problem of how Adobe does some funky things on first run, it hashes hardware information about the system. So, you must run the CS3 app twice the first time. When you run it once it asks for license key, well that is embedded in the install, so it hashes all the info the firs time you run it. Quit the app and re-run it and it will have that hashed info and never ask for a license key again. We of course a site license. I also have an inventory of how many installs I have done, which is right around 150 right now so i am well below my limit of what a site license is.

It also does everything via ssh, so its secure.

My problem is, that I am sort of a scripting newbie. I know bash very well, but when it comes to writing variables and loops, and things like that I don't quite fully grasp all of it just yet. I mean I read your script and realized it deleted everything except the exempt folders, but I wouldn't be able to write that script you wrote from scratch - if that makes sense.
tlarkin is offline   Reply With Quote
Old 02-19-2008, 02:19 PM   #14
Mikey-San
Hall of Famer
 
Join Date: Jan 2002
Posts: 3,541
For your task, if you just want to target a couple of specific folders, you probably don't need anything fancy. Couple more questions:

1. Under what user privilege will the script run?

2. You've got a few ways to trigger it (log in, every X minutes, etc), so you can go a couple of different routes here. Examples:

A. When User A logs in, the script is triggered and it deletes the specified folders in User A's home dir.

B. Every X minutes/hours/whatever, the script is triggered and it deletes the specified folders for all users.

C. At boot, the script is triggered and it deletes the specified folders for all users.

Which do you think you want to do? (I would think at boot or log in, yeah?)
__________________
COMPUTER TYPE
SOME SPECIFICATIONS I COPIED FROM THE BOX
STUFF I INSTALLED ALL BY MYSELF
"WITTY QUOTE"
Mikey-San is offline   Reply With Quote
Old 02-19-2008, 02:28 PM   #15
tlarkin
League Commissioner
 
Join Date: Mar 2003
Location: Bay Area, CA
Posts: 11,351
Quote:
Originally Posted by Mikey-San
1. Under what user privilege will the script run?

Root

Quote:
2. You've got a few ways to trigger it (log in, every X minutes, etc), so you can go a couple of different routes here. Examples:

- When User A logs in, the script is triggered and it deletes the specified folders in User A's home dir.

or

- On boot or every X minutes/hours/whatever, the script is triggered and it deletes the specified folders for all users.

Which do you think you want to do?


This is not totally relevant to the scripting process I would think. Since I can set all of that via the policy scope, and I can change it via the casper client. For this particular need I would do it, once per a machine as the frequency, so once a single computer has the script ran on it, it will mark it as done and won't run it again, and then have it delete these preferences out of every local home directory on the laptop. We do home synchronization here, so their home is sync'd over the network. That way they can authenticate locally to the machine if outside our network.

All my options though are adjustable via the web front end of the casper server. like I said it is a really nifty product. Which is why my scripting skills are kind of weak. since I can do most things with the client, and the client uses the under the hood unix, I really haven't been challenged enough to learn some heavy scripting. If you know of any crash course scripting websites I would be more than happy to look through them. I have a desire to learn this stuff. All of my scripts have been like maybe 5 lines at the most, which includes your line of explaining what the script does.

**EDIT oh yeah thanks again for helping, I'd email you a beer if that was possible!

Last edited by tlarkin; 02-19-2008 at 03:03 PM.
tlarkin is offline   Reply With Quote
Old 02-19-2008, 03:35 PM   #16
Mikey-San
Hall of Famer
 
Join Date: Jan 2002
Posts: 3,541
The scripting process would be affected if you were doing it every time at login, since you could do something super-simple that just deletes the specified folders in the home dir of the user who just logged in. But if you want to nuke 'em for all users at once, we'll go a similar route to what I did above. So, lemme make sure I got it straight:

1. The script runs with superuser privileges.

2. The script will be invoked by you, the sysadmin, at will, but you can also set it to run periodically automatically.

3. The script will remove the target directories from all home folders, at once, on the client machine.

Do I have it right?
__________________
COMPUTER TYPE
SOME SPECIFICATIONS I COPIED FROM THE BOX
STUFF I INSTALLED ALL BY MYSELF
"WITTY QUOTE"
Mikey-San is offline   Reply With Quote
Old 02-19-2008, 03:45 PM   #17
Mikey-San
Hall of Famer
 
Join Date: Jan 2002
Posts: 3,541
As for learning, I recommend:

http://tldp.org/LDP/abs/html/

It's very straightforward, builds steadily, and doesn't overload you. (There's an example in the intro that is complicated, but it's just a demonstration of complexity, not something it expects you to understand at first. When you're done with the book, you'll grasp the example.)

There are a couple of O'Reilly books on Unix/bash scripting, but I don't know much about them, so I wouldn't be able to make a recommendation.
__________________
COMPUTER TYPE
SOME SPECIFICATIONS I COPIED FROM THE BOX
STUFF I INSTALLED ALL BY MYSELF
"WITTY QUOTE"
Mikey-San is offline   Reply With Quote
Old 02-19-2008, 03:53 PM   #18
tlarkin
League Commissioner
 
Join Date: Mar 2003
Location: Bay Area, CA
Posts: 11,351
Correct.

Since users that I support often at times trade laptops, or one user will borrow another user's laptop to quickly check email or what not, sometimes their are multiple users synchronized with their network home on a single laptop. Now, if I run the scope at once per a user I run the risk of the user not being the actual owner of the machine. But, if I do it at a scope of once per a machine, then I can hit all the users in /users and just be done with it, also they will receive the new package at the same time and be marked in inventory as being updated.

So yes your assumptions are correct

1. yes, it runs as a local admin account on the system. There is a specific local hidden admin account that is used for the ssh session that the casper client/server have. So, all scripts will be executed as if the local admin were running them, so sudo may be needed.

2. Correct again, I will most likely set the policy to run once per a machine and be triggered by any, which includes log in/out, reboot, or every 15 minutes.

3. It will remove specific user data that is stored in each users home, mainly preferences. This is because when I push out a new software application package and it requires new settings because we changed something I need to delete the old user preferences. Otherwise, it will install and use all the old user preferences and thus won't work properly.

Thanks for the link, I book marked it and am reading through it now. Got text wrangler up and running and am going to start creating scripts I think I may need in the future and go from there.

Thanks a ton!
tlarkin is offline   Reply With Quote
Old 02-19-2008, 06:12 PM   #19
Hal Itosis
Hall of Famer
 
Join Date: Apr 2002
Posts: 3,315
Quote:
Originally Posted by tlarkin
3. It will remove specific user data that is stored in each users home, mainly preferences. This is because when I push out a new software application package and it requires new settings because we changed something I need to delete the old user preferences. Otherwise, it will install and use all the old user preferences and thus won't work properly.

As far as this part goes, I think hayne's wildcarding suggestion will work well.
You can test it with something like:

ls -ld /Users/*/Library/{Application\ Support/MyAppFolder,Preferences/MyAppFolder}

Only... sudo isn't enough for the wildcard pattern-matching to work (from a Terminal)... unless,
you put those lines in a script, and then call the entire script with sudo. [or simply run from a
root shell... so sudo wouldn't be necessary.]

The reason something like sudo ls -ld /Users/*/Library/Application\ Support doesn't work in Terminal
is that our shell does the '*' expansion before passing it to sudo... so not all matches get to happen.

Contrast that with:
$ sudo bash
# ls -ld /Users/*/Library/Application\ Support

Then it works!

...or put the lines in a script, and do sudo myscript

[there's a thread around here somewhere in which hayne struggled to teach me that principle. ]

-HI- <sometimes i'm not easy>

Last edited by Hal Itosis; 02-19-2008 at 06:24 PM.
Hal Itosis is offline   Reply With Quote
Old 02-19-2008, 06:38 PM   #20
hayne
Site Admin
 
Join Date: Jan 2002
Location: Montreal
Posts: 32,386
Quote:
Originally Posted by Hal Itosis
The reason something like sudo ls -ld /Users/*/Library/Application\ Support doesn't work in Terminal
is that our shell does the '*' expansion before passing it to sudo... so not all matches get to happen.


True enough in general- but in this particular case, the /Users folder is readable and searchable by all, so the expansion of the * under your current (non-root) user account should suffice to give the desired result.

[edit]
My comment in this post is incorrect - see discussion in posts #24 and #25 below
[/edit]
__________________
hayne.net/macosx.html

Last edited by hayne; 02-19-2008 at 11:33 PM.
hayne is offline   Reply With Quote
Reply

Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



All times are GMT -5. The time now is 04:08 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.