98

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?

apaderno
  • 1,464
  • 3
  • 23
  • 38
Wolfy87
  • 1,083
  • 1
  • 8
  • 8

12 Answers12

98

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.
  • 1,130
  • 8
  • 7
79

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.

Y. E.
  • 105
  • 4
Scott
  • 5,853
  • 1
  • 21
  • 33
  • 2
    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 Nov 08 '13 at 22:17
  • @Scott, thank you. This is the most helpful answer I found on the internet. – Dmitriy Feb 10 '14 at 15:04
  • 12
    This 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 `LaunchOnlyOnce` to the dict. – msanford Apr 12 '16 at 17:17
  • 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 Oct 22 '16 at 23:52
  • 1
    Note to self: If you need environment variables: https://serverfault.com/questions/111391/use-an-environment-variable-in-a-launchd-script – Quandary Mar 23 '17 at 13:07
  • Should I expect `launchctl load` to load directly or should I logout/login? (or maybe just kill the WindowServer?) – Kamafeather Feb 26 '19 at 18:34
50

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
  • 627
  • 5
  • 3
  • 6
    best 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 Aug 08 '16 at 03:01
  • 7
    However, login items run at login, not at system startup. If you run a server, that's a big difference. – not2savvy Jul 14 '17 at 15:40
  • 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 Jul 14 '17 at 16:57
  • 5
    Why ends with `cmd` instead of `sh`? – Cloud May 20 '18 at 06:44
  • 2
    Whether your Library script path ends in cmd or sh, this won't necessarily actually _execute_ the script, when invoked in this fashion. In my case (macOS 10.15.4 Catalina), it opens it in XCode (sh) or Visual Studio Code (cmd) instead, which obviously isn't useful. – ecmanaut Apr 18 '20 at 20:45
  • @Simin Jie because I thought it would guarantee that the system would execute the script instead of opening it in an editor. But as ecmanaut writes this is not the case. – Geekarist May 25 '20 at 07:14
  • 4
    This only works when you have associated `cmd` or `sh` with the Terminal app in macOS! In my cas my script ended with `.sh` and that extension was associated with Xcode. On every login, the file was opened in Xcode instead of being executed. After changing the application association in Finder, it worked fine. – fabb Sep 10 '20 at 05:38
  • 2
    I didn't get the option to associate the file with Terminal - that was greyed out. But using a `.command` extension did the trick for me (from https://stackoverflow.com/questions/25580918/open-a-shell-script-in-terminal-mac-no-matter-what-the-default-application-for) – Sam Sep 10 '21 at 16:30
49

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

mmmmmm
  • 6,013
  • 29
  • 32
  • 1
    So 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 Jan 06 '11 at 11:45
  • 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 Jan 06 '11 at 12:07
  • @Scott is correct I have corrected my answer – mmmmmm Jan 06 '11 at 12:14
  • 4
    Okay, 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 Jan 06 '11 at 12:27
  • 1
    @Mark link to "launchd" is broken :( – Artem Nov 07 '16 at 05:10
13

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
  • 1,395
  • 2
  • 13
  • 25
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
  • 11,068
  • 1
  • 21
  • 26
1

Although I do not find the answers that are asking you to add the call in .bash_profile or .bashrc acceptable, they could work imho.

You could right click on your Terminal Icon when on Dock, Select Options > Open at login.

I have an auto-login VPN script for work. I need to open Terminal too when working. So I prefer it automatically launches at startup and I used .bashrc to run my vpn script automatically.

Sahil Bawa
  • 11
  • 2
  • Welcome to Super User! Before answering an old question having an accepted answer (look for green ✓) as well as other answers ensure your answer adds something new or is otherwise helpful in relation to them. Here is a guide on [answer]. There is also [tour] for the site tour, and [help] for the help center. – help-info.de Feb 24 '22 at 15:22
  • There is one answer suggesting that, which has -4 votes; for good reasons: when placed in .bashrc or .bash_profile the service would start every time you open a terminal window or login elsewhere. – mashuptwice Feb 24 '22 at 15:43
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.

user907666
  • 11
  • 1
0

You could use crontab:

First, create a script somewhere (let's say /path/to/script.sh) and type the command you wanted to run there. Then type chmod +x /path/to/script.sh.

Now, in the Terminal:

EDITOR=nano crontab -e

You will be presented with a text editor in the terminal.

Type in the file:

@reboot /path/to/script.sh

Hit Ctrl + X, hit y, and hit enter, and on the next boot, this will run!

If you wanted to run a command in the background, simply add an & after the command in the script.

DarkDiamond
  • 1,875
  • 11
  • 12
  • 19
bobtho'-'
  • 1
  • 2
0

This answer explains how to run a command on at login and is based on Geekarist's answer. Here, the script is wrapped in an AppleScript application. AppleScript was chosen over a workflow, because the Script Editor application does not overwrite manual changes made to an applications Info.plist file, where as the Automator application does. Wrapping the script in an application also allows the user to customize privacy settings. If the script exits with a non-zero status, then the application shows a popup window with an error message. Otherwise, no other windows are shown.

Steps are given below.

  1. Use the Script Editor application to create a application containing the line given below.

    do shell script quoted form of (POSIX path of (path to me) & "Contents/Resources/Startup.sh")
    
  2. Save the application to your ~/Applications folder. (If this folder does not exist, then create the folder.) Here, I will name the application "My Agent". You may choose a different name.

  3. Create a file named Startup.sh in My Agent application's Contents/Resources folder. Place the script in the file. A copy of the script from Geekarist's answer is given below.

    #!/bin/bash
    
    # Start the MongoDB server
    /Applications/MongoDB/bin/mongod --dbpath /usr/local/mongo/data --fork --logpath /usr/local/mongo/log
    
  4. Enter the command given below to make Startup.sh executable.

    chmod +x ~/Applications/My\ Agent.app/Contents/Resources/Startup.sh
    
  5. Make the My Agent application an agent. This will prevent (amongst other things) the My Agent application from appearing on the dock while executing at startup.

    /usr/libexec/PlistBuddy -c "Add :LSUIElement bool true" ~/Applications/My\ Agent.app/Contents/Info.plist
    

    The above command adds the following lines to My Agent application's Info.plist file.

        <key>LSUIElement</key>
        <true/>
    
  6. Open the My Agent application in the Script Editor application. Compile the script, save and quit. This is necessary, because the Info.plist file was manually changed in the previous step.

  7. Add the My Agent application to the user login items.

David Anderson
  • 883
  • 1
  • 8
  • 13
-1

Open Terminal app select Terminal preferences go to profiles select Profiles Under Startup enter source path to script script Name

Patrick M
  • 1
  • 1
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 05 '22 at 21:16
-5

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
djsmiley2kStaysInside
  • 6,643
  • 2
  • 31
  • 43
MAX
  • 1