How do I pass command line arguments to Dock items?

75

64

I'm attempting to follow the instructions for pinning startup tabs in Chrome. On OS X how do I add command line arguments to items that persist in my dock?

sudoer

Posted 2011-04-16T16:43:14.587

Reputation: 851

Answers

99

You have basically two options:

Option 1: Use Automator to create an application that in effect launches Chrome with command line arguments.

Start Automator and select to create an Application. Double-click Run Shell Script in the Library/Utilities folder and replace the text content — cat — with the following:

open -a "Google Chrome.app" --args -pinned-tab-count=4
# keep the .app suffix or will break with Parallels

Save anywhere you like.

To replace this application's icon, Get Info on your real Google Chrome, click on the icon on the top left, press Cmd-C, Get Info on your Chrome Automator app, click the icon, and press Cmd-V.

Since it's a different application, the Dock will display two Chrome applications when it's running: Chrome, and your Chrome launcher.


Option 2: Edit your application bundle to launch a script instead. This script will start the actual application, adding the command line argument.

Right-click Google Chrome.app and select Show Package Contents. Go to Contents/ and open Info.plist in Property List Editor/Xcode (Apple's developer tools), or a third party plist editor.

Look for the entry CFBundleExecutable or Executable File. Remember its value (e.g. firefox-bin for Firefox). Replace it with parameterized-app.sh.

Open Terminal and enter the following:

touch /Applications/Firefox.app/Contents/MacOS/parameterized-app.sh
open /Applications/Firefox.app/Contents/MacOS/parameterized-app.sh

An editor for the .sh file will open. Set the contents of the file to:

#!/usr/bin/env bash
exec /Applications/Firefox.app/Contents/MacOS/firefox-bin -ProfileManager

(using the actual executable's name you removed from Info.plist, adding the desired command-line arguments)

Save and close. In Terminal, enter the following:

chmod +x /Applications/Firefox.app/Contents/MacOS/parameterized-app.sh

Now, close Terminal and move your application (which must not be running right now) to a different folder and back again. This will update Launch Services, otherwise your changes will be ignored and irritate you immensely.

Now, when you open your application, it will actually execute the .sh file, which will in turn launch the actual executable file, sending the command line args along.

It will look and behave like you expect it to, but you will need to repeat this whenever you update your application, as this will generally replace the application bundle and all the changes you made.

Daniel Beck

Posted 2011-04-16T16:43:14.587

Reputation: 98 421

1@Jordan Brough You can use the lsregister utility to force a LaunchServices update: /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f /Applications/Hello\ World.app – Will Ross – 2014-11-29T16:29:15.880

1Of course, Option 2 only works on non-CodeSign apps. If it comes from apple or the app store, it's signed against changes. Even a change to Info.plist will stop it. In that case, a simple stub/wrapper app would help. – cde – 2015-10-02T20:32:36.267

Thanks. I am now always launching Google Chrome with the debug log enabled. But will this be overwritten by Google Chrome's automatic updates? – steven_noble – 2017-05-11T23:54:36.213

Awesome. I needed to open Chromium and Canary in incognito at all times for dev testing. This really made things faster for me. – sdkks – 2017-10-27T01:58:48.797

For some reason open --args don't work with Chrome. I tried with --user-data-dir, it's completely ignored. – Pacerier – 2017-12-15T17:25:43.013

Tried this with Steam and it worked the first time, but after that when I tried to launch it with the icon from the Dock it replaced this data completely, and in each attempt since it launches and "crashes", then replaces the data, and then launches properly without the modifications. Really sucks, because their latest updates don't run very well on my 7yo MBP, and there are launch options that help, but I have to open it through the terminal each time instead. This is still awesome though -- thank you! – l3l_aze – 2018-07-28T08:51:12.363

1I tried the first technique using open with Thunderbird and needed to add -n ("Open a new instance of the application(s) even if one is already running."): open -n -a "Thunderbird.app" --args --new-instance -P profile-name This is in Mojave. – Paused until further notice. – 2019-04-23T22:59:57.807

For some reason, my Chrome 10 ignores the command line argument and auto-pins the tabs that were pinned in the previous session. Don't know what's wrong here, as I'm not a Chrome user and don't know how it's supposed to behave. – Daniel Beck – 2011-04-16T18:14:34.230

Thanks for Info.plist hack and hint to move the .app folder! – Art – 2011-08-24T23:41:27.040

6"move your application to a different folder and back again" should be bold - completely missed it on first read :) – stephanos – 2013-10-27T10:14:28.473

1Is there a way to update/reset/restart Launch Services via a shell command so that you don't have to move the application out and back again? i.e. so that that step is easily scriptable? – Jordan Brough – 2014-04-10T16:45:55.683

10

You could write a script that launches Chrome, but that wouldn't be the application icon in the dock, and it would cause a separate Chrome icon to appear. So you'll have to create an application package.

First, make a copy of your Chrome app. Then, there are two approaches that might work; I'm not sure which will play better with Mac OS X and/or Chrome's self-update.

  1. Make a 'launcher' that just calls Chrome with the arguments.

    • Open the app package (right-click → Show Package Contents in the Finder), and throw out everything but Info.plist, PkgInfo, and MacOS.
    • In the MacOS folder, delete the “Google Chrome” executable and replace it with a shell script that calls the real Chrome:

      #!/bin/sh
      exec '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' -pinned-tab-count=4
      

      Don't forget to chmod +x the script.
       

  2. Modify the Chrome package you actually run.

    • In the MacOS folder, rename “Google Chrome” and write a shell script which invokes the real thing with the extra arguments:

      #!/bin/sh
      exec '/Applications/My Modified Google Chrome.app/Contents/MacOS/Google Chrome-real' -pinned-tab-count=4
      
    • I see the Chrome package has something about code signing; you might need to delete the CodeResources and/or _CodeSignature to get it to run with these changes.

This is all based on my understanding of Mac app packages; I haven't actually tested these changes on Chrome in particular. It is even posible that the Chrome executable on Mac doesn't support this option, as Mac applications are generally not expected to be run with controllable command-line options (unlike, for example, Windows, where applications are normally launched via shortcuts which can have embedded options).

Kevin Reid

Posted 2011-04-16T16:43:14.587

Reputation: 2 854

Chrome support parameters, I just automated mine following your instruction #2. You do indeed need to specify the full path for the binary, and don't forget to chmod 755 Google\ Chrome (your script) after you've finished. I actually named my script launch.sh and symlinked it to Google\ Chrome for ease of updates. – Orwellophile – 2015-05-25T13:14:07.753

Note that modifying package contents causes problems with code signing, resulting in odd problems like https not working properly: https://bridge.grumpy-troll.org/2011/01/macos-x-changing-argv-the-troll-erred/

– drevicko – 2019-07-05T01:47:26.733