89

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
  • 2,389
  • 5
  • 27
  • 28
  • 2
    I'm still hoping for better answers on this one... – cregox Oct 30 '10 at 02:34
  • 1
    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 Jan 22 '11 at 13:00
  • look for Daniel's answer - it's the most complete and perfect for today (OSX 10.6.2 +). – cregox Jan 26 '11 at 19:03
  • 2
    FUTURE GOOGLERS: the `open` command has an `--args` argument: `open -a FireFox --args -ProfileManager` does exactly what you want. – alexchandel Apr 14 '21 at 12:26

10 Answers10

45

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
  • 551
  • 4
  • 5
  • 1
    "man open", and there it is! worked like a charm. --args flag and then your arguments. – Michael Dimmitt Oct 08 '17 at 16:21
  • 2
    I 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 Dec 15 '17 at 22:39
  • 1
    @Pacerier, "open -n" – Simon Wright Jul 18 '18 at 21:18
  • To add to this, you can create the script in Script Editor and then save as application. – Kevin C. Jan 05 '19 at 21:06
  • 1
    As @SimonWright replied but didn't explain the `-n` flag opens a new instance of the application. – Jerinaw Dec 02 '20 at 01:32
23

This answer is obsolete.

Refer to other answers for modern Mac OS.

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
  • 1,410
  • 9
  • 15
  • 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 Aug 01 '09 at 12:10
  • 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 Aug 01 '09 at 12:14
  • Also, I notice I put a newline in before the &. Remove the newline if you have it – MJeffryes Aug 01 '09 at 12:16
  • 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 Oct 30 '10 at 02:52
  • I'm not sure what you mean. Is the script app not being killed? Because that's what the &killall is for. – MJeffryes Oct 30 '10 at 09:58
  • @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 Jan 26 '11 at 19:02
  • @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 Feb 04 '12 at 10:01
  • @MJeffryes nevermind .. the line from the second answer from the bottom will work... anyways.. thx – pixelass Feb 04 '12 at 10:04
  • Yea fine but how do you "save it as an application" using AppleScript? Remember some people are new to Mac. – whitneyland Jul 01 '13 at 14:16
  • 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 Jun 18 '15 at 04:02
  • omg, @Andrew I just discovered: open has an --args flag, your example ```Opera --args -kioskmode``` – Michael Dimmitt Oct 08 '17 at 16:20
  • @MJeffryes, Why wouldn't it work from the script editor? – Pacerier Dec 15 '17 at 22:03
  • @Andrew, What debugger? Clarify... – Pacerier Dec 15 '17 at 22:35
  • Also, what I don't understand is **why would you need to kill the app for?** – Pacerier Dec 15 '17 at 22:37
  • 2
    @Pacerier Check the dates on this answer. – MJeffryes Dec 16 '17 at 12:55
23

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
  • 109,300
  • 14
  • 287
  • 334
  • 2
    Just keep in mind the `open --args` was implemented in 10.6.2, as Bob already mentioned. – cregox Jan 26 '11 at 19:04
  • Using it for: `open eclipse.app -n` to open a second Eclipse workspace. Very handy. Thanks! – jonalv Nov 01 '11 at 09:19
  • 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. Jan 05 '19 at 21:06
  • 1
    Works great for me on Catalina. – jerclarke Jan 02 '20 at 16:45
  • 1
    @KevinC. This didn't work for you? `/Applications/Firefox.app/Contents/MacOS/firefox-bin -ProfileManager &` I did a test run in Automator and that worked. Then I saved it to my Applications folder as a .app file and launched it from there - that worked too. I'm also running macOS 10.14 (Mojave). – Mentalist Jul 07 '20 at 13:44
  • You can do `open -a Firefox --args -ProfileManager ` from an Automator Application's "Run Shell Script" too. `open` is more canonical than `&` and `nohup`, and won't cause unexpected problems. prefer `open` unless you need the child's PID to be yours. – alexchandel Apr 14 '21 at 12:25
15

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
  • 686
  • 2
  • 8
  • 26
10

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
  • 39,401
  • 6
  • 111
  • 111
  • 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 Mar 14 '11 at 00:49
  • 2
    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](http://developer.apple.com/library/mac/#releasenotes/AppleScript/RN-AppleScript/RN-10_1/RN-10_1.html%23//apple_ref/doc/uid/TP40000982-CH101-SW13), which came with Mac OS X 10.1). If you are willing to assume 10.6, then `open --args` is probably fine. – Chris Johnsen Mar 14 '11 at 03:01
  • @ChrisJohnsen, Link down........ – Pacerier Dec 15 '17 at 22:43
10

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
  • 121
  • 1
  • 2
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
  • 41
  • 1
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
  • 531
  • 5
  • 7
  • 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 Aug 01 '09 at 11:34
  • 1
    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 Jul 05 '19 at 01:45
3

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
  • 31
  • 1
1

Why don't you use:

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

Simple but it works.