View Full Version : Run script at login?

Aug 13, 2007, 03:21 PM
I have a script I want to run whenever a user logs in. The script is stored at /.login/login.sh

This seemed fairly straightforward, I made the script executable, then executed sudo defaults write com.apple.loginwindow LoginHook /.login/login.sh
It seemed to work, in that it returned no error, and sudo defaults read com.apple.loginwindow returns {LoginHook = "/.login/login.sh"; }

The problem is that it doesn't work. And I have no idea why. Can anyone enlighten me? I'm running 10.4.10



Aug 13, 2007, 04:58 PM
.login should be a file. put all your stuff in that file.

Aug 13, 2007, 05:16 PM
If you want to run the script for your account only, you could also rename the script to login.command, give it appropriate permissions, and add it to your Login Items in System Preferences. The script will be executed in Terminal though, instead of in the background.

Aug 13, 2007, 06:06 PM
First, read up on launchd and launchd.plist either online or in terminal using the man command. Once you have an idea what these do, download Lingon (http://lingon.sourceforge.net/) a free plist editor/creator.

The basic idea is this:
1. Create your script
2. Create a new .plist in Lingon and choose the appropriate options. The most important ones are:
Program Arguments >> path to script
runAtLoad >> will run when the user logs on
3. Click save & load and there you have it. Make sure your script is executeable (chmod 770 <pathToScript>)

As mentioned there are other ways to do this, but using launchd is the best way to run scripts at startup in Tiger.

Aug 13, 2007, 06:12 PM
Ok, so I've been playing around with launchd, but I'm having trouble with its reliability. It seems like it doesn't always work. I suspect that the problem is that it isn't unloading my script before the next login sometimes, is there a way to make sure that as soon as "exit 0" is called in my script it unloads it?

Aug 13, 2007, 06:55 PM
How did you choose to run the .plist? You can run per user at login, all users at login, or system wide at startup. I had a few problems with reliability at first, but that was when I was doing everything in terminal. Once I started using lingon everything just worked (and who knows why.) I tried all sorts of other methods (login items, applescript, .command files) and none performed as well as using launchd.

Sorry if I can't be much more help.

Edit: Also, make sure the only option checked is RunAtLoad.

Aug 13, 2007, 07:25 PM
I have to confess that I'm using vim and the built in .plist editor. I'll try give lingon a shot.

How do you set whether it goes per user, global, etc? Ideally I would like it to only run for the user "guest", so I just put the .plist in /Users/guest/Library/LaunchAgents/

I have RunAtLoad set.

Let me give lingon a shot and see what happens,



Aug 13, 2007, 08:04 PM
What happens if you make your script runnable by renaming it with .command as the extension, can you then place it in your startup items?

Aug 13, 2007, 08:49 PM
>How do you set whether it goes per user, global, etc?

When you hit 'New' it will give you a sheet with all the options. Simple.

>Ideally I would like it to only run for the user "guest", so I just put the .plist in /Users/guest/Library/LaunchAgents/

Correct..well, in theory. I have only done this from the user's account. So if you do this from Admin account, for example, after you move the file it might not work properly until the plist is loaded into that account (using either launchctl or lingon.) I don't know about this one.

I too started out using vi only to pull my hair out for hours. While I like doing things the hard way (terminal is my favorite app!) Lingon makes everything so much easier. Don't have to deal with manually editing plist files (athough you can do that in lingon) and you avoid launchctl all together.

good luck!

Aug 14, 2007, 01:33 PM
Well it seems to be working now, but only as long as I 'unload' the thing (holding down command in Lingon so as not to disable it) before logging out. Obviously this is inconvenient given that I don't want the user to know it exists at all. Would it be Bad(tm) to make the script unload itself?

Aug 14, 2007, 07:36 PM
You shouldn't have to 'unload' it. It should run each time the user logs in. Perhaps there is something in your script that requires a restart rather than a simple logout? What does your script do? The scripts I wrote do simple things (mount network volumes, keep 'sleepy' firewire drives awake, create 'daily' folders for assets.)

Aug 15, 2007, 10:06 AM
The script is 3 lines, it runs isightcapture to capture a .jpeg from the isight, then runs uuencode and mail to attach the picture to an email and send it to me. The last line is 'exit 0', is that even necessary?

Aug 16, 2007, 03:04 AM
Ok, so I got rid of the 'exit 0' and replaced it with a line telling launchctl to unload the .plist, and now I can sit here and launch the thing over and over again and it works flawlessly every time so far as I can tell. It might have something to do with the isightcapture utility, it keeps giving me weird problems with permissions and stuff. Anyway, whatever the problem was it seems to be working now, thanks for all the help,


Aug 16, 2007, 09:04 AM
Cool, glad you got it all working. Also, the isightcapture app has made it into my utilities folder; great find! Much fun lies ahead.

Aug 16, 2007, 11:58 AM
If you stick it in /usr/bin (or one of the other bin directories too I should think) you can run it from the command line with just 'isightcapture'.

Here is what I'm working on:
isightcapture picture.jpg
uuencode picture.jpg thief.jpeg | mail -s Thief youremail@server.com
launchctl unload /Users/guest/Library/LaunchAgents/IDCheck.plist

Create an account called 'guest' (with no password), use Lingon to create IDCheck.plist (or change the name to match in the script) which runs at login, and put your email address in the script. Whenever someone logs in to the guest account (which they will be forced to do after they steal your laptop and your account has a password) it emails you a picture of them (the picture will show up in Mail and various other mail clients, but does not show in the web based gmail reader). I'm currently working on switching to using mutt so the picture will be more compatible with web based mail readers, and having it include the LAN and WAN IP addresses in the email. I also need to make it more stealthy so the thief doesn't find a picture of themself sitting in their home directory and get suspicious....

This will require wget and mutt (I got them using fink, there might be easier ways if you don't already have fink):
wget www.whatismyip.org
isightcapture picture.jpg
ifconfig | mutt -s "Laptop Stolen" -a picture.jpg -a index.html youremail@server.co
rm index.html
rm picture.jpg
launchctl unload /Users/guest/Library/LaunchAgents/IDCheck.plist
That will send you an email with the contents of ifconfig (which tells you bunches of stuff about your LAN connection) in the body, and with an index.html copied from www.whatismyip.org attached (telling you the WAN IP) as well as a snapshot from the isight. Between those 3 things you really should have everything you need to track down the thief as long as you can get law enforcement to play along (and the picture should really help too).

Aug 16, 2007, 12:47 PM
First thing that comes to mind is to name the picture something like ._picture.jpg so the file is invisible in finder. Don't know if that will cause problems with the email though.

Also, what does uuencode do?

Aug 16, 2007, 01:08 PM
Also, what does uuencode do?

encode a binary file

Aug 16, 2007, 02:31 PM
I had the whole script and everything in an invisible directory, but was getting lots of annoying permissions problems and stuff (unrelated to it being hidden actually) so I moved it. The updated script I posted above just deletes the picture as soon as its done with it, so unless they find the script itself (I'm going to hide it and give it a non descript name), or the .plist file (same routine, although I'm not sure how hiding it will effect it) there really isn't much to let them know whats going on. And if you just chown both of those to root or yourself and give them execute but not write permissions there really isn't much they can do about it even if they find them.

A bigger problem is that the little light on the camera lights up briefly, so I'm hoping they will write that off as an initialization thing. They can always cover up the camera if they figure out what is going on, but unless they know about this thing in advance I should get at least 1 picture from their first login. From there on out I just need updates on their IP, which they can really only prevent from sending by playing games with the network (I'm not sure what this script does if it has no internet, but one way or another I don't see how it could work).