How can I run an application with command line arguments in Mac OS

60

30

Is there any easy way to append command line arguments to an application on a Mac? For example, to run Opera in kiosk mode or to use a different profile in Firefox, I can type

$ /Applications/Opera.app/Contents/MacOS/Opera -kioskmode
$ /Applications/Firefox.app/Contents/MacOS/firefox -P profilename -no-remote

In Windows I can append the arguments to the shortcut properties, but since Macs don't use shortcut per se and run the applications directly, this isn't possible.

I have found that launching the applications through bash or Applescript partially works:

# Bash
#!/bin/sh
/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote

# Applescript    
do shell script "exec /Applications/Opera.app/Contents/MacOS/Opera -kioskmode"

I can make these executable and assign an icon and everything works great except that when I run either of these pseudo programs, either a terminal window or an Applescript icon remains open as long as the application is open. Presumably, using the Applescript command open would avoid this, but since I'm not running the application as it is packaged (just /Applications/Firefox), it doesn't work.

So, is there a better way to run applications with command line arguments? If not, is there a way to prevent a persistent terminal session or Applescript icon from staying open while the application is open?

Edit

According to a Mozilla Wiki page, it's best to use a script to run the application with arguments. Adding a & to the end of the script kills the persistent Terminal window. The only annoyance now is that it opens a dead, logged out Terminal window (which is better than the persistent one, but still...)

#!/bin/sh
/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote &

Andrew

Posted 2009-08-01T09:24:24.340

Reputation: 1 869

2I'm still hoping for better answers on this one... – cregox – 2010-10-30T02:34:00.333

When you run a job with & it still belongs to the Terminal, you can fix that by adding the line disown %/Applications/Firefox.app/Contents/MacOS/firefox after you run it, then you can safely close the Terminal, using AppleScript. – ocodo – 2011-01-22T13:00:55.513

look for Daniel's answer - it's the most complete and perfect for today (OSX 10.6.2 +). – cregox – 2011-01-26T19:03:35.997

Answers

18

Here's my best solution: Create an Applescript with:

do shell script "/Applications/Firefox.app/Contents/MacOS/firefox -P default -no-remote & killall Firefox.app"

And save it as an application.

You can put whatever application with whatever args in the first part. The part after the & needs to kill whatever you have named your script + .app. You'll see the script app flash up in the dock, but it will then disappear.

Note: The script will not work properly when run from Script Editor, only when run from the script application you have created.

MJeffryes

Posted 2009-08-01T09:24:24.340

Reputation: 1 292

I'm on Yosemite. The app runs just fine. However, when I close the app, it remains on the dock - pinned. Which would be fine except that if I click it.. it doesn't go away. Any help? – abjbhat – 2015-06-18T04:02:41.947

It almost works. It's still waiting for the Firefox instance to be done until it runs killall, so it calls the debugger when I close Firefox, and the script app still doesn't go away. Hmmm... – Andrew – 2009-08-01T12:10:00.260

That's weird. Are you saving it as an App then double clicking the App? It won't work when run from Script Editor. – MJeffryes – 2009-08-01T12:14:41.997

Also, I notice I put a newline in before the &. Remove the newline if you have it – MJeffryes – 2009-08-01T12:16:22.507

omg, @Andrew I just discovered: open has an --args flag, your example Opera --args -kioskmode – Michael Dimmitt – 2017-10-08T16:20:24.510

@MJeffryes, Why wouldn't it work from the script editor? – Pacerier – 2017-12-15T22:03:42.087

@Andrew, What debugger? Clarify... – Pacerier – 2017-12-15T22:35:33.957

Also, what I don't understand is why would you need to kill the app for? – Pacerier – 2017-12-15T22:37:40.393

1@Pacerier Check the dates on this answer. – MJeffryes – 2017-12-16T12:55:32.527

no need for &killall here at Snow Leopard 10.6.x - but also couldn't find any way to make the app kill it self as soon as executing. – cregox – 2010-10-30T02:52:41.550

I'm not sure what you mean. Is the script app not being killed? Because that's what the &killall is for. – MJeffryes – 2010-10-30T09:58:41.727

@ziggamorph I'm sorry, I also don't know anymore wtf I meant. I have to police myself more on to what I write. – cregox – 2011-01-26T19:02:18.417

@MJeffryes So how would this line look for "Google Chrome" ? Obviously 'do shell script "/Applications/Chrome.app/Contents/MacOS/Google Chrome -P default -no-remote & killall Chrome.app"' won't work – pixelass – 2012-02-04T10:01:58.557

@MJeffryes nevermind .. the line from the second answer from the bottom will work... anyways.. thx – pixelass – 2012-02-04T10:04:46.027

Yea fine but how do you "save it as an application" using AppleScript? Remember some people are new to Mac. – whitneyland – 2013-07-01T14:16:28.747

30

Starting in OS X 10.6.2, the open command can pass arguments to the application it opens by way of the --args flag. An AppleScript to use it looks like this:

do shell script "open -a /Applications/Firefox.app --args -P default -no-remote"

That should give you all the behavior you want.

Bob

Posted 2009-08-01T09:24:24.340

Reputation: 401

"man open", and there it is! worked like a charm. --args flag and then your arguments. – Michael Dimmitt – 2017-10-08T16:21:52.477

1I tried --args with Chrome and it doesn't work. It will only work for the first instance. If you try to run two --user-data-dir concurrently, you can't do it with open but must run it by the old /applications... method. Anyone know why the fuck does --args not work? – Pacerier – 2017-12-15T22:39:48.353

1@Pacerier, "open -n" – Simon Wright – 2018-07-18T21:18:40.313

To add to this, you can create the script in Script Editor and then save as application. – Kevin C. – 2019-01-05T21:06:56.430

14

Open Automator and create an Application with a single Run Shell Script action:

 /Applications/Firefox.app/Contents/MacOS/firefox-bin -here-some-args &

This application will launch Firefox and quit instantly, leaving only Firefox running.


Alternatively, create an application using AppleScript Editor with the following AppleScript code:

do shell script "open -a '/Users/danielbeck/Applications/Firefox.app' --args -ProfileManager"

Both work fine and don't keep either Terminal or a script application running for more than a second or so. Using Automator, you can even create a Service if you choose so.

Daniel Beck

Posted 2009-08-01T09:24:24.340

Reputation: 98 421

Couldn't get it to work in Automator with "Run Shell Script" action in MacOS 10.14. I ended up having success with the AppleScript, though. – Kevin C. – 2019-01-05T21:06:43.280

Works great for me on Catalina. – jerclarke – 2020-01-02T16:45:31.780

1Just keep in mind the open --args was implemented in 10.6.2, as Bob already mentioned. – cregox – 2011-01-26T19:04:31.923

Using it for: open eclipse.app -n to open a second Eclipse workspace. Very handy. Thanks! – jonalv – 2011-11-01T09:19:52.363

8

It is not necessary (as some other answers have suggested) to use killall (or similar) to kill the parent AppleScript application process (“applet”) in this scenario. It can even have untoward side effects if the name/pattern given to killall matches more than just the parent applet process (e.g. other, concurrently running AppleScript applications (if using “applet” as the pattern)).

Something like kill $PPID might be more reasonable, but we may not want to assume that the applet of an AppleScript application is always the immediate parent of the shell started by do shell script. Luckily, there is a perfectly reasonable way to do what you need.

Per TN2065 (under “I want to start a background server process; how do I make do shell script not wait until the command completes?”), the proper method is to redirect stdout and stderr and have the shell run the program in the background.

Use Script Editor to save the following program as an AppleScript application:

do shell script ¬
    "/Applications/Firefox.app/Contents/MacOS/firefox-bin \\
        -P default -no-remote \\
        >/dev/null 2>&1 &"

(functional line breaks added to keep it “narrow”; delete the ¬ and \\ and put it all on one long line if you like)

It will run long enough to start Firefox and will exit cleanly while Firefox continues to run.

The redirection is required because not only does do shell script wait for its immediate child (the shell) to exit, but it also waits for (all instances of) the writable ends of the pipes it creates for the shell’s stdout and stderr to be closed. The shell’s stdout and stderr (do shell script’s pipes) are inherited by the programs it runs without redirection (even ones run in the background with &); the redirection ensures that the shell is the last one to hold the writable ends of the pipes. Thus, do shell script will return immediately after the shell exits, allowing the AppleScript application itself to exit (since the do shell script is the last expression in the AppleScript program).

The other answers that use open inside do shell script work because open (actually LaunchServices) does the equivalent work of backgrounding the resulting program and sending its stdout and stderr elsewhere.

Chris Johnsen

Posted 2009-08-01T09:24:24.340

Reputation: 31 786

@ChrisJohnsen, Link down........ – Pacerier – 2017-12-15T22:43:54.917

this is very interesting. I wonder if it works prior to 10.6.2 ... but I still think using open --args looks cleaner. is there any drawback on using any of them? – cregox – 2011-03-14T00:49:45.127

1

I know this method works in 10.4. My impression is that do shell script has always worked like this (it was added to the Standard Additions OSAX in AppleScript 1.7, which came with Mac OS X 10.1). If you are willing to assume 10.6, then open --args is probably fine.

– Chris Johnsen – 2011-03-14T03:01:18.757

8

This is a old discussion, but still comes up on Google searches, so I thought I'd add a couple of ¢.

It's probably better to use a "bundle identifier" rather than absolute path to the executable:

open -b com.google.Chrome --args --profile-directory="Profile 1"

Or in an Apple Script:

do shell script "open -b com.google.Chrome --args --profile-directory='Profile 1'"

What I have not figured out yet is how to open a new instance/window with a different profile once the first one is already open. (If I run the AppleScript above, then another with "Profile 2", then Chrome will still just open another window as "Profile 1"). :(

user1722483

Posted 2009-08-01T09:24:24.340

Reputation: 101

Is -b functionally equal to -a? How are they different? – Pacerier – 2017-12-15T22:52:46.607

4

AppleScript

do shell script "/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --incognito & killall applet"

Two points there.

  1. The space is escaped by a backslash which is escaped by backslash again
  2. killall applet can cause troubles, because there may other applets running
  3. Save it as program

However it works well on 10.6.5

anonymous

Posted 2009-08-01T09:24:24.340

Reputation: 41

applet refers to? – Pacerier – 2017-12-15T23:24:23.677

3

The following should let you specify command-line arguments for the .app itself:

Right click .app bundle, select "Show Package Contents", navigate to Info.plist, double click it, find Args key, edit.

I don't have an OS X machine handy right at the moment, so I can't check whether you could also do this to an alias (if you wanted to keep the original .app argument-free, et cetera).

Dav

Posted 2009-08-01T09:24:24.340

Reputation: 521

There's no args key in the plist, unfortunately. According to Mozilla, you're supposed to use a script - https://wiki.mozilla.org/MailNews:Logging#Mac

– Andrew – 2009-08-01T11:34:29.300

Note also that changing package contents (such as Info.plist) can cause issues with code signing: https://bridge.grumpy-troll.org/2011/01/macos-x-changing-argv-the-troll-erred/

– drevicko – 2019-07-05T01:45:40.653

2

Wrap your application inside an AppleScript launcher.

Here are the steps.

  1. Create an AppleScript with the following content, and save it as an application (in this example it is named "Firefox 3 launcher.app").

    set pathToApp to (POSIX path of (path to me)) & "Firefox 3.app"
    do shell script "open -a \"" & pathToApp & "\" --args -P default -no-remote"
    
  2. Got to that app in the Finder, right click it, show package contents.

  3. Put your application in the root of the package contents. (In this example it would be "Firefox 3.app")

    Result: /Applications/Firefox 3 launcher.app/Firefox 3.app

  4. You may now open your application launcher.

Notes:

  • Automatic updates of the wrapped application should work in most cases.
  • It should be possible to make any drag and drop to the launcher automatically redirected to the wrapped application (with a bit more scripting).
  • The launcher automatically exits after the wrapped application is launched.
  • An advantage of this method is that there is few risks of opening the wrapped application directly.

jlgrall

Posted 2009-08-01T09:24:24.340

Reputation: 21

1

The open command has an optional --args argument that's value will be passed on to the opened application as arguments. For example:

open /Applications/TextEdit.app --args example.txt

ecnepsnai

Posted 2009-08-01T09:24:24.340

Reputation: 436

1

Why don't you use:

#!/bin/sh
open /Applications/Firefox.app

Simple but it works.

None

Posted 2009-08-01T09:24:24.340

Reputation:

2The terminal will open if you do that. – MJeffryes – 2009-08-01T11:56:56.470