Run command on startup / login (Mac OS X)

56

31

I was wondering which file I should place this bash command in so it will be run on startup.

# Start the MongoDB server
/Applications/MongoDB/bin/mongod --dbpath /usr/local/mongo/data --fork --logpath /usr/local/mongo/log

I have been scouring the net and think it is between ~/.bashrc, ~/profile, /etc/bashrc, /etc/profile or ~/.bash_profile. Although I have tried these and they seem to run on terminal startup not Mac startup. Am I missing a file?

Wolfy87

Posted 2011-01-06T11:24:35.233

Reputation: 663

Answers

35

Officially none of these. The Apple suggested way is to use launchd. Guis to set this up include lingon and Launch Control

As for the files you mention the ones in the home directory ~/.bashrc, ~/profile, ~/.bash_profile are only started when you login via a terminal. The ones in /etc are run by the shell starting for all users before the ones in home directory but only when a user login is made.. bash manual

The Unix startup script involved /etc/rc* but for OSX just use the launchd stuff

user151019

Posted 2011-01-06T11:24:35.233

Reputation: 5 312

1@Mark link to "launchd" is broken :( – Artem – 2016-11-07T05:10:46.353

1So if my command is inserted in either of the files in /etc it should be run on bootup? Does it matter what one it is in? – Wolfy87 – 2011-01-06T11:45:42.993

1/etc/bashrc and so on are run when you start a shell, just like ~/.bashrc - it's just that the former will be run whenever any user starts a shell, rather than just your user. – Scott – 2011-01-06T12:07:30.897

@Scott is correct I have corrected my answer – user151019 – 2011-01-06T12:14:13.397

4Okay, but I just can't work out how to use launchd, I tried making a plist file for my program but I have no idea how to run it or how to get it to run on boot. – Wolfy87 – 2011-01-06T12:27:09.337

60

To run a command on start up on OS X, you need to use launchd.

If you don't want to use Lingon, you need to create a launchd Property List. This is an XML file, so you can do it with your favourite text editor or alternatively you can use the Property List Editor that's installed with the Mac OS X Dev Tools. Create the following:

<?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>some.meaningful.name</string> <!-- org.mongodb.mongodb perhaps? -->

    <key>OnDemand</key>
    <false/>

    <key>UserName</key>
    <string>anAppropriateUser</string>

    <key>GroupName</key>
    <string>anAppropriateGroup</string>

    <key>ProgramArguments</key>
    <array>
            <string>/Applications/MongoDB/bin/mongod</string>
            <string>--dbpath</string>
            <string>/usr/local/mongo/data</string>
            <string>--fork</string>
            <string>--logpath</string>
            <string>/usr/local/mongo/log</string>
    </array>
</dict>
</plist>

Save this in /Library/LaunchAgents/some.meaningful.name.plist (you will need an administrator account and/or sudo), then open a terminal and do:

sudo launchctl load /Library/LaunchAgents/some.meaningful.name.plist

This will cause launchd to load the item which will cause it to start MongoDB on boot. As a bonus, launchd will monitor it and, if it exits for any reason, it will be re-started. To get rid of the item simply replace load in the above command with unload.

Scott

Posted 2011-01-06T11:24:35.233

Reputation: 5 323

6This will attempt to run the application every 10 seconds, which works well for services that don't die. If this is for a script that runs once punctually (in my case, messaging once Slack on reboot) add <key>LaunchOnlyOnce</key><true/> to the dict. – msanford – 2016-04-12T17:17:15.177

Great point Mr Sanford. launchd which doesn't give up creates huge log files which then slow your Mac (due to reading and writing such large log files continually). I may use that fix on some of the badly written commercial software running on my computer now. – Foliovision – 2016-10-22T23:52:49.870

1

Note to self: If you need environment variables: https://serverfault.com/questions/111391/use-an-environment-variable-in-a-launchd-script

– Quandary – 2017-03-23T13:07:32.527

Should I expect launchctl load to load directly or should I logout/login? (or maybe just kill the WindowServer?) – Kamafeather – 2019-02-26T18:34:12.387

1

This page (https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/launchd.plist.5.html#//apple_ref/doc/man/5/launchd.plist) lists a lot of things something launched by launchd should not do. If I want to run an arbitrary command at startup I may not have control of and the command may wind up doing those things. In addition, I may not want launchd to restart and item that stops because it's a one-off or handles re-launching on its own. What should I do in these cases?

– Michael – 2013-11-08T22:17:50.523

@Scott, thank you. This is the most helpful answer I found on the internet. – Dmitriy – 2014-02-10T15:04:00.270

51

Another simple solution from Stack Overflow: You can:

  • Start Automator.app;
  • Select "Application";
  • Click "Show library" in the toolbar (if hidden);
  • Add "Run shell script" (from the Actions/Utilities);
  • Copy-and-paste your script into the window;
  • Test it;
  • Save it somewhere: a file called your_name.app will be created);
  • Depending your MacOSX version:
    • Old versions: Go to System Preferences → Accounts → Login items, or
    • New version: Go to System Preferences → Users and Groups → Login items (top right);
  • Add this newly-created app;

Log off, log back in, and you should be done. ;)

Jaime M.

Posted 2011-01-06T11:24:35.233

Reputation: 660

4It does, however, add about 1804k of boilerplate to your three line shellscript! – android.weasel – 2015-09-16T14:06:41.350

1Thanks for the detailed instructions on making something useful with Automator. This will help me not just with the one task. Thank you kindly Jaime. I'm using it to turn off Turbo Boost via Turbo Boost Switcher. I own the pay version but the licensing mechanics are awful enough I prefer to use the free version which requires launch via terminal to avoid requests for admin password on every wake from sleep. – Foliovision – 2016-10-22T23:33:39.423

1

@android.weasel See Geekarist's answer http://superuser.com/a/995564/255375

– J.D. – 2017-01-16T14:59:00.267

Superuse-ful :-D, +1 – Mukul Goel – 2017-07-10T11:04:05.183

suuuuuper cool thx – Walrus the Cat – 2017-10-02T02:37:27.313

2Tested and works and it does not require launchd cumbersome plist editing nor paid Lingon app. – Lukasz – 2012-10-02T08:13:20.113

30

To launch commands when logging in, you can do this:

  • Create a text file containing your commands (bash script):

    #!/bin/bash
    
    # Start the MongoDB server
    /Applications/MongoDB/bin/mongod --dbpath /usr/local/mongo/data --fork --logpath /usr/local/mongo/log
    
  • Save this file in ~/Library/Startup.cmd

  • You can test it by double-clicking the file in the Finder
  • Make it executable: chmod +x ~/Library/Startup.cmd
  • Add this file in System Preferences > Accounts > Login items

Geekarist

Posted 2011-01-06T11:24:35.233

Reputation: 409

3best and easiest answer imho. much easier than accepted solution. note that it's in System Preferences > Users & Groups > Login items ... (not Accounts)... and also note that the file can be anywhere, doesn't have to end with .cmd either. just chmod +x it. – foreyez – 2016-08-08T03:01:07.263

6However, login items run at login, not at system startup. If you run a server, that's a big difference. – not2savvy – 2017-07-14T15:40:02.147

You're right @not2savvy. For a server I would recommend @Sridhar-Sarnobat's answer with @reboot.

However my answer would allow to start a graphical program, that's why I think it's useful. – Geekarist – 2017-07-14T16:57:29.773

Why ends with cmd instead of sh? – Simin Jie – 2018-05-20T06:44:51.457

3

If you want an approach that will work on Linux & Mac OS X, a cron task should should be sufficient (edit your cron tasks by executing crontab -e):

@reboot /path/to/script

(credits: https://unix.stackexchange.com/questions/49207/how-do-i-set-a-script-that-it-will-run-on-start-up-in-freebsd)

Sridhar Sarnobat

Posted 2011-01-06T11:24:35.233

Reputation: 870

3

You will have to look at how launchd and launchctl work on MacOS. You could start by reading the man pages for both the commands. You could then look inside /Library/LaunchAgents/ and /Library/LaunchDaemons/ for examples of how to set up applications to load at different times through the launchctl interface.

Here's an example I found on Stack Overflow that might help you further.

ayaz

Posted 2011-01-06T11:24:35.233

Reputation: 8 106

0

I was interested in a very simple unix answer to this problem and found it at another site. Here is a summary of the solution.

The standard for login shells is to always look for the bash configuration files with "profile" in the name, in this order: /etc/profile, ~/.bash_profile, then ~/.bash_login and lastly ~/.profile. When login shells exit, they read ~/.bash_logout.

In my case I just created the ~/.bash_profile and then I opened the preferences for the Mac Terminal app and changed the "Shell opens with" option from default to /bin/bash. That's it. Clean and simple.

markgp

Posted 2011-01-06T11:24:35.233

Reputation: 11

-3

open terminal, type

nano ~/.bash_profile

then add this text to the file:

/Applications/MongoDB/bin/mongod --dbpath /usr/local/mongo/data --fork logpath /usr/local/mongo/log

MAX

Posted 2011-01-06T11:24:35.233

Reputation: 1

3This would assume you open a Terminal window after logging in. – Arjan – 2017-03-11T07:42:42.330