Friday, January 29, 2010

Using Firefox profiles on Mac OS X

If you are a Firefox power user, you are probably familiar with its profile system. A profile is a folder where Firefox keeps all your customizations, history, bookmarks, cookies, and other data.

Firefox lets you run several independent instances using different profiles simultaneously -- by specifying special options in the command line. The basics are covered in this lifehacker article.

Unfortunately on Mac OS X there's no easy way to specify command line parameters in a "shortcut", like there is on Windows. The well-known workarounds are:
  1. Use Terminal.app or similar to execute /Applications/Firefox.app/Contents/MacOS/firefox-bin with the necessary parameters.
  2. Use a separate launcher application like MultiFirefox, which is similar to Firefox's own profile manager, and also lets you choose the Firefox version to run.
  3. Use Script Editor.app to create an "application" that runs Firefox with the command-line parameters you want.
  4. Create multiple slightly edited copies of Firefox.app that run with the specified profile.
I used a combination of these until recently, and they're all imperfect: the first and second workarounds require several steps to run Firefox, and the third option was too slow for me. The fourth just seems wrong.

My solution

This solution was tested with Mac OS X Leopard, Snow Leopard, and Lion. We create a lightweight bash-based application, which starts Firefox with the right command line arguments.

You can download a zip with the template application, which should show the profile manager when run (assuming you have Firefox installed to the standard location).

Here's how you create this application:

  1. Create a folder /Applications/FirefoxWork.app with a folder Contents inside it. (To open an *.app folder in Finder use the context menu Show Package Contents.)
  2. Inside the Contents folder create a file named Info.plist (note: all names are case sensitive!) with the following contents:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
      <key>CFBundleExecutable</key>
      <string>FirefoxLauncher</string>
      <key>CFBundleIdentifier</key>
      <string>com.example.FirefoxLauncher</string>
      <key>CFBundleInfoDictionaryVersion</key>
      <string>6.0</string>
      <key>CFBundleName</key>
      <string>FirefoxLauncher</string>
      <key>CFBundlePackageType</key>
      <string>APPL</string>
      <key>CFBundleSignature</key>
      <string>????</string>
      <key>CFBundleVersion</key>
      <string>1.0</string>
    </dict>
    </plist>
    (the meaning of these keys is explained in the Core Foundation Keys reference).
  3. Inside Contents create another subfolder named MacOS.
  4. Save the following to a file called FirefoxLauncher in the MacOS folder:
    #!/bin/bash
    /Applications/Firefox.app/Contents/MacOS/firefox-bin -no-remote -P work &
    Adjust the path to Firefox and the profile name as appropriate.
    Update: You may need to prepend arch -i386 to the command if you're trying to run newer Firefox (version 4 and later) on Mac OS X 10.5.
    Update 2: (thanks to Daniel Beck on superuser.com for this tip) you can use open instead to avoid hardcoding the path to the application and the binary name:
    #!/bin/bash
    open -n -a Firefox.app --args -no-remote -P work
  5. Run chmod u+x /Applications/FirefoxWork.app/Contents/MacOS/FirefoxLauncher in the terminal to make the script executable.
  6. Now test if the program runs by executing open /Applications/FirefoxWork.app.
    • If you get an error saying "LSOpenFromURLSpec() failed with error -10810 for the file /Applications/FirefoxWork.app.", most probably the script couldn't be run - either the name in CFBundleExecutable parameter didn't match the actual script name in MacOS or the file doesn't have the execute bit set (see chmod command above).
      If you edited Info.plist, be sure to touch FirefoxWork.app to invalidate OS X's cache. 
  7. Voila! You can now drag FirefoxWork.app to the dock or run the application via QuickSilver and it doesn't take a second to run the shell script.

6 comments:

  1. It's worth noting that the application name can be changed, it doesn't have to be "FirefoxWork". It may also be necessary to put the profile name in quotes if it contains a space. To round thing out, I also changed the app's icon to one of the ones mentioned in the Stackoverflow answer http://superuser.com/a/75285/57398.

    ReplyDelete
  2. I put a comment on superuser, but it is probably more relevant here:
    This looks like a nice solution. However I got a: LSOpenURLsWithRole() failed with error -10665 for the file /Applications/FirefoxWork.app

    And if I try to open it with the finder, it says that this is a powerpc application and that it is no longer supported. Any idea what I could do wrong ?

    ReplyDelete
    Replies
    1. Interesting.. Does running the script directly from the terminal work?

      /Applications/FirefoxWork.app/Contents/MacOS/FirefoxLauncher

      Delete
    2. Now that I got it working, I have a real question. I now have 2 icons in my dock, with 2 different profiles. However, when I click on any of them, it opens a third app (the real firefox app). And if I start the other profile, I now have a fourth firefox. Anyway to prevent this from happening by any chance ?

      Delete
    3. Thanks! I will fix the post and try to upload the template elsewhere.

      Re dock icons - I don't have this problem. Here's how I set it up: I have the regular Firefox.app pinned to the dock, which runs with the default profile. I have the launcher for the other profile I use, but don't pin it to the dock (instead I launch it from Spotlight)

      Delete
  3. Ok found it, I did not put the "#!/bin/bash", only "open ..." since it was not very clear ;-).
    Thanks !

    ReplyDelete