Set Firefox profile directly within the application bundle

Nov 17, '09 07:30:01AM

Contributed by: Anonymous

I share a computer with my wife (using one account), and we both use Firefox and many of the same services (Gmail, Facebook, etc.). As such, it can be quite a hassle to keep track of who logged in last and who added what bookmarks.

Fortunately, Firefox provides the capability to have separate profiles for just such a situation. Unfortunately, it is not very simple to set up an easy and consistent way to launch those profiles. So, here are some of the options I tried before arriving at what I think is a pretty good solution.

Option 1: Use the profile manager. In this mode, the profile manager will pop up every time Firefox is launched and you can choose your profile. This is nice and all, but what if my wife wants to launch Firefox while I already have it open? If she clicks the Firefox icon in the Dock, it just brings the app to the front and does not give the profile manager dialog.

Option 2: Create a script that will call the profile directly. This option is close to a good solution, since I can have separate scripts for each profile, solving the second instance issue of Option 1. However, this option creates extra Firefox icons in the Dock, and it can be confusing to figure out which instance is which.

Option 3: Create an entire copy of Firefox.app, and edit the contents of each copy to launch a specific profile. Say, for example, that the profile name is Bob. First I would create a copy of Firefox.app and rename it Firefox-Bob.app. Next, I run a fancy script (see below) that scans the /Applications directory and modifies Firefox-Bob.app to launch the Bob profile directly.

This means there is only one Dock icon for the instance of Firefox-Bob, and clicking that icon brings Firefox-Bob to the front. The one drawback to this method is that each time Firefox needs to auto update, it will blow away the profile modification. This is not really a big deal, however, since all you need to do is re-run the script to reset things.

Here's the script (also available via DropBox):

#!/bin/bash

# Go into Applications folder
cd /Applications > /dev/null

# Get a list of all files of form Firefox-Username.app
ls -1 | grep Firefox- | \
while read line
do

    # Go into the app package contents
    pushd $line/Contents/MacOS > /dev/null

    # Check to see if this app has already been converted.
    # If the file is binary then it has NOT ben converted yet.
    isBinary=`file firefox-bin | grep binary`

    if [ -n "$isBinary" ] # Will be true if isBinary is NOT empty (i.e. it IS binary)
    then

        # Get the username from the app name.
        user=`echo $line | sed "s/Firefox-\(.*\)\.app/\1/"`

        # Print some feedback
        echo Converting $line for user $user

        # Move the binary file to a new spot
        mv firefox-bin firefox-bin1

        # Write the following lines into a file with the same name as the previous
        # binary file, firefox-bin
        echo '#!/bin/bash' >> firefox-bin
        echo '/Applications/'$line'/Contents/MacOS/firefox-bin1 -P '$user' &' >> firefox-bin
        echo sleep 3 >> firefox-bin
        echo osascript -e "'tell application \"Firefox-$user\" to activate'" >> firefox-bin

        # Make the newly written file executable.
        chmod a+x firefox-bin
    else

        # Just like the feedback says, don't do anything since this file is
        # not a binary file.
        echo $line has already been converted.  No changes made.
    fi

    # Go back out of the package so we're ready to process the next one (if any)
    popd > /dev/null

done

# This part is a bit of bash foo.  The command above is actually a single command with
# a three part pipe (ls | grep | while read line).  The PIPESTATUS is indexed by
# the location in the pipe sequence, 0, 1, 2, ...  So, the risk of failure here
# is that the grep will not find a matching sequence.  Thus the error we're after
# is index 1.
err=${PIPESTATUS[1]}
if [ $err -ne 0 ]
then
    # Say something meaningful to STDERR so it will show up
    # even if it is being called from applescript.
    echo "Could not find any files to convert in the" >&2
    echo "Applications folder!" >&2
    echo >&2
    echo "Files must match the form Firefox-Profilename.app" >&2
    echo "where Profilename is the actual profile name to use." >&2
fi
exit $err
You can probably figure out what is going on by looking at the contents of the script, but here is what I'm doing to the application's contents:
  1. Rename /Applications » Firefox-Bob.app » Contents » MacOS » firefox-bin to firefox-bin1.
  2. Create a shell script called firefox-bin that calls firefox-bin1 with the -p Bob argument.
  3. Make the shell script executable.
  4. Add a touch of AppleScript to bring the instance of Firefox-Bob to the front after it launches.
[robg adds: I haven't tested this one. Separate accounts for each user would seem like a good alternative solution, but perhaps they have good reasons for using but one account.]

Comments (17)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20091106222902593