Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Easily run a script on login in the background UNIX
This hint is for those that wish to run an AppleScript or shell script every time on login, but want it to happen quietly in the background without appearing in the dock.

Open up ScriptEditor in the Applications folder and paste in this code. Then save this AppleScript as an Application Bundle to some location. Go to this location and control-click on the script and choose "Show Package Contents" and go into Contents -> Resources -> Scripts. Drop your shell script in there (mine is called script.sh; make sure to edit the first line of the AppleScript to reflect the script's name). Finally, to make the whole thing invisible, open up the Info.plist file inside of the Contents folder of the AppleScript application. Right after the very first line, paste this in:
<key>NSUIElement</key>
<string>1</string>
Save the plist file and quit the editor. Now test your script by double-clicking on the script application. Apple seems to have some weird bug that will sometimes still cause it to appear in the dock. If this happens, simply duplicate (command-D) the script application and the duplicate should work. Finally, drop this script app into your Login Items in System Preferences, and you're set to go. Thanks to Ryan for help with this and this old hint for the posix_path() function.

[robg adds: I haven't tested this one...]
    •    
  • Currently 3.57 / 5
  You rated: 5 / 5 (7 votes cast)
 
[29,103 views]  

Easily run a script on login in the background | 7 comments | Create New Account
Click here to return to the 'Easily run a script on login in the background' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Easily run a script on login in the background
Authored by: thomas_witt on May 31, '05 11:09:34AM

works like a charm. by the way, you don't need to duplicate. it's enough when you drag the app to the desktop and then back to the folder. it's appearently a caching issue.



[ Reply to This | # ]
Easily run a script on login in the background
Authored by: sapporo on May 31, '05 12:40:35PM
launchd would be the proper way to do this.

[ Reply to This | # ]
Easily run a script on login in the background
Authored by: morgion on May 31, '05 02:00:35PM

Any insights (your instructions, doc links, 'man' pages) into doing this through launchd?



[ Reply to This | # ]
RE: launchd
Authored by: nicksay on May 31, '05 08:13:59PM

I don't think launchd is actually the universal "better" way. It has some limitations (more on those at the end). As a side note, see Oneota's comment below — to get the "UNIX" version of a file path in AppleScript, you can use the builtin POSIX path function that's part of Standard Additions. Back to the subject, here's a little more info THAT I've found about launchd:

Links Example

You can follow the instructions over at Mac Geekery for another use of launchd items, but relevant to this disscussion are LaunchAgents. launchd controls two types of processes: LaunchDaemons, which are system-wide and are loaded at startup, and LaunchAgents, which are per-user and loaded at login. From the man page for launchd:

FILES
      ~/Library/LaunchAgents         Per-user agents provided by the user.
      /Library/LaunchAgents          Per-user agents provided by the administrator.
      /Library/LaunchDaemons         System wide daemons provided by the administrator.
      /System/Library/LaunchAgents   Mac OS X Per-user agents.
      /System/Library/LaunchDaemons  Mac OS X System wide daemons.
So the general case will be to place a launchd item in the first directory, the user's LaunchAgents folder.

Creating the Script

If we want to run a script at login, one first has to save the script somewhere. I chose ~/Library/Scripts/Applictions/launchd/ because I thought it made logical sense and it won't show up in the script menu because it's in an Applications subdirectory. I created the following script:

#!/bin/bash
echo Hello World > /Users/YOURUSERHERE/Desktop/HelloWorld.txt
and saved it as an executable file named HelloWorld in the above folder. Replace "YOURUSERHERE" with your short username (i.e. your home directory).

Creating the launchd Item

You can either use PropertyListEditor or any text editor to create the launchd item. The file should be saved at ~/Library/LaunchAgents/. I used PropertyListEditor:

  1. Create a new document, create a new root, and expand it.
  2. Create 3 children and name them Label, ProgramArguments, and RunAtLoad.
  3. Set Label to a string with a reverse-domain-style identifier (e.g. com.example.userlogin).
  4. Set ProgramArguments to an array. Add 1 child and set it to a string with the path to your script (e.g. /Users/YOURUSERHERE/Library/Scripts/Applications/launchd/HelloWorld).
  5. Set RunAtLoad to a boolean that's false.
  6. Save the file as the value of Label and a plist extension (e.g. com.example.userlogin.plist)

After you've saved it, or if you're using a text editor, the file should look like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.example.userlogin</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Users/YOURUSERHERE/Library/Scripts/Applications/launchd/HelloWorld</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>
Again, replace "YOURUSERHERE" with your short username (i.e. your home directory). Now you can test your LaunchAgent by opening Terminal and running launchctl load Library/LaunchAgents/com.example.userlogin.plist. You should see a HelloWorld.txt file on your Desktop. Delete it and as a final test log out and log in. You should see the file on your Desktop as you log in.

Problems

If your LaunchAgent isn't working, check Console and see if launchd has thrown any errors. One example:

launchd[6156]: com.example.userlogin: exited with exit code: 1
You can add a key titled Debug with a boolean value that's false to your launchd item and run the test on the command-line. (You might need to unload the item first (e.g. launchctl unload ... before loading it again.) When you run it with the Debug value set to true, errors and output go to the command-line instead of to Console.

launchd Limitations

Now, as I said, I don't think that launchd is the be-all-and-end-all of login-item-replacement. Not yet, anyway. First, it's designed only for command-line scripts or programs. It's also designed for programs that run in the background (i.e. daemons). So, there is no user interaction. I couldn't even get it to run an AppleScript. (I put /usr/bin/osascript as my first ProgramArguments item and the path to my script as the second.) I think the problem is that LaunchAgents are run so early in the login process that AppleScript doesn't function. (I tried both a display dialog and a do shell script. Incidentally, even when testing from the command-line, you need to tell System Events to display dialog because user interaction is prevented from osascript directly.) I don't think interaction with other applications will work because your script will be called before they are even launched or made available to AppleScript. However, for things like executing configuration shell scripts or running up a user-level copy of MySQL or starting a ssh-agent session, LaunchAgents do work very well in replacing login-items.

So that's what I've found that is relevant. Thoughts?

[ Reply to This | # ]
RE: launchd
Authored by: jaydisc on Jun 01, '05 07:04:35PM
I have a LaunchDaemon that uses osascript with an applescript as its argument. This is to run an AppleScript to update a DNS server of my newly changed dynamic IP. This is stored in /Library/LaunchDaemons and runs regardless of a user being logged in. It is set to rerun every 15 minutes:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/Proper$
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>com.xxxxxx.nsupdate</string>
        <key>LowPriorityIO</key>
        <true/>
        <key>Nice</key>
        <integer>1</integer>
        <key>ProgramArguments</key>
        <array>
                <string>osascript</string>
                <string>/usr/local/bin/nsupdate.scpt</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>ServiceDescription</key>
        <string>nsupdate service</string>
        <key>StartInterval</key>
        <integer>900</integer>
</dict>
</plist>


[ Reply to This | # ]
Easily run a script on login in the background
Authored by: Oneota on May 31, '05 04:55:19PM

Why are you writing your own path POSIX-fixer? Can't you just do "POSIX path of (path to my item)"? I use that all the time and haven't run into a case where it fails....



[ Reply to This | # ]
Easily run a script on login in the background
Authored by: jdratlif on Apr 04, '10 03:59:38PM

The launchd thing looked promising, but the script I was running needed my ssh key, and launchd wouldn't open ssh-agent to ask for the passphrase. But the AppleScript thing in login items worked perfectly.



[ Reply to This | # ]