如何在Mac OS中使用命令行参数运行应用程序


60

在Mac上,是否有任何简单的方法可将命令行参数附加到应用程序?例如,要在信息亭模式下运行Opera或在Firefox中使用其他配置文件,我可以输入

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

在Windows中,我可以将参数附加到快捷方式属性中,但是由于Macs本身并不使用快捷方式而是直接运行应用程序,因此这是不可能的。

我发现通过bash或Applescript启动应用程序部分有效:

# 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"

我可以使这些可执行文件并分配一个图标,并且一切正常,但是当我运行这些伪程序中的任何一个时,只要打开应用程序,终端窗口或Applescript图标都会保持打开状态。大概,使用Applescript命令open可以避免这种情况,但是由于我没有运行打包的应用程序(只是/Applications/Firefox),所以它不起作用。

因此,是否有更好的方法来运行带有命令行参数的应用程序?如果不是,是否有一种方法可以防止在打开应用程序时持续的终端会话或Applescript图标保持打开状态?

编辑

根据Mozilla Wiki页面,最好使用脚本来运行带有参数的应用程序。&在脚本的末尾添加a 将终止持久性Terminal窗口。现在唯一的烦恼是它打开了一个死的,已注销的终端窗口(这比持久窗口要好,但仍然...)

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

2
我仍然希望对此有更好的答案……
cregox

当您运行的任务&仍属于终端时,可以通过disown %/Applications/Firefox.app/Contents/MacOS/firefox 在运行后添加该行来解决此问题,然后可以使用AppleScript安全地关闭终端。
ocodo 2011年

寻找Daniel的答案-它是当今最完整,最完美的(OSX 10.6.2 +)。
cregox 2011年

Answers:


17

这是我最好的解决方案:使用以下方法创建Applescript:

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

并且将其保存为一个应用程序

您可以将带有args的任何应用程序放在第一部分。&需要杀死的部分之后,无论您将脚本+ .app命名为什么。您会看到脚本应用程序在扩展坞中闪烁,但随后将消失。

注意:仅当从已创建的脚本应用程序运行时,该脚本在从“脚本编辑器”运行时将无法正常运行。


它几乎可以工作。它仍在等待Firefox实例完成运行,直到运行killall,因此当我关闭Firefox时它将调用调试器,并且脚本应用程序仍然不会消失。嗯...
安德鲁

这很奇怪。您是否将其另存为应用程序,然后双击该应用程序?从脚本编辑器运行时,它将不起作用。
MJeffryes'09年

另外,我注意到我在&之前加上了换行符。如果有,请删除换行符
MJeffryes

无需在Snow Leopard 10.6.x上使用&killall进行操作-但也找不到任何方法使应用程序在执行后立即自行杀死。
cregox

1
@Pacerier检查此答案的日期。
MJeffryes

28

从OS X 10.6.2开始,open命令可以通过--args标志将参数传递给它打开的应用程序。要使用的AppleScript如下所示:

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

那应该给你所有你想要的行为。


“人开”,就在那里!像魅力一样运作。--args标志,然后输入您的参数。
迈克尔·迪米特

1
我尝试--args使用Chrome,但无法正常工作。它仅适用于初审。如果尝试同时运行两个--user-data-dir,则不能使用它,open而必须使用旧/applications...方法运行它。有人知道为什么他妈的不起作用--args 吗?
佩里耶

1
@Pacerier,“ open -n”
Simon Wright

为此,您可以在“脚本编辑器”中创建脚本,然后另存为应用程序。
Kevin C.

11

打开Automator并使用一个Run Shell Script操作创建一个应用程序

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

该应用程序将启动Firefox并立即退出,仅保留Firefox运行。


或者,使用带有以下AppleScript代码的AppleScript编辑器创建应用程序:

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

两者都可以正常工作,并且不会使Terminal或脚本应用程序运行超过一秒钟左右。如果选择使用Automator,甚至可以创建服务


1
只需记住open --args,如Bob所述,它是在10.6.2中实现的。
cregox 2011年

使用它来:open eclipse.app -n打开第二个Eclipse工作区。非常便利。谢谢!
jonalv

无法通过MacOS 10.14中的“运行Shell脚本”操作使它在Automator中工作。但是,我最终在AppleScript上获得了成功。
Kevin C.

8

这是一个古老的讨论,但是仍然会出现在Google搜索中,因此我想加几分。

最好使用“捆绑标识符”而不是可执行文件的绝对路径:

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

或在Apple脚本中:

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

我还没有弄清楚的是,一旦第一个实例/窗口已经打开,如何用其他配置文件打开它。(如果我运行上面的AppleScript,然后运行另一个带有“配置文件2”的AppleScript,那么Chrome仍然会打开另一个窗口作为“配置文件1”)。:(


-b在功能上是否等于-a?它们有何不同?
Pacerier '17

7

在这种情况下,没有必要(如一些其他答案所建议的那样)使用killall(或类似的方法)杀死父AppleScript应用程序进程(“ applet”)。如果指定给killall的名称/模式匹配的不仅仅是父子applet进程(例如,其他同时运行的AppleScript应用程序(如果使用“ applet”作为模式),则它甚至可能具有不利的副作用。

诸如此类的东西kill $PPID可能更合理,但我们可能不想假设AppleScript应用程序的applet始终是do shell script所启动的Shell的直接父级。幸运的是,有一种完全合理的方法可以满足您的需求。

根据TN2065(在“我想启动后台服务器进程;如何使Shell脚本不等到命令完成之前?”下),正确的方法是重定向stdout和stderr并使Shell在后台运行程序。

使用脚本编辑器将以下程序另存为AppleScript应用程序:

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

(添加功能换行符,以保持它“窄”;删除¬\\并把它全部在一个长行,如果你喜欢)

它会运行足够长的时间以启动Firefox,并且在Firefox继续运行时会干净退出。

重定向是必需的,因为shell脚本不仅会等待其直接子级(shell)退出,而且还会等待(其所有实例)它创建的管道的可写端以关闭shell的stdout和stderr 。shell的stdout和stderr(做shell脚本的管道)是由它运行的程序继承而无需重定向的(即使那些程序在后台也带有&);重定向可确保外壳是容纳管道可写端的最后一个外壳。因此,do shell脚本将在shell退出后立即返回,从而允许AppleScript应用程序本身退出(因为do shell脚本是AppleScript程序中的最后一个表达式)。

使用open inside 的其他答案可以使shell脚本工作,因为open(实际上是LaunchServices)所做的等效工作是将结果程序后台化并将其stdout和stderr发送到其他地方。


这很有趣。我想知道它是否在10.6.2之前有效...但是我仍然认为使用open --args看起来更干净。使用它们有什么缺点吗?
cregox 2011年

1
我知道此方法在10.4中有效。我的印象是shell脚本一直像这样工作(它被添加到Mac OS X 10.1附带的AppleScript 1.7中Standard Additions OSAX中)。如果您愿意接受10.6,则可能很好。open --args
克里斯·约翰森

@ChrisJohnsen,链接关闭........
佩里耶

4

苹果脚本

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

有两点。

  1. 该空间由反斜杠转义,反斜杠再次转义
  2. Killall小程序可能会引起麻烦,因为可能还有其他小程序正在运行
  3. 将其另存为程序

但是它在10.6.5上运行良好


applet是指?
佩里耶

3

以下应该使您可以为.app本身指定命令行参数:

右键单击.app bundle,选择“显示软件包内容”,导航到Info.plist,双击它,找到Args键,进行编辑。

我目前没有一台OS X机器,因此无法检查是否也可以对别名进行此操作(如果您想保持原始的.app无参等)。


不幸的是,plist中没有args键。根据Mozilla的说法,您应该使用脚本-wiki.mozilla.org/MailNews:Logging#Mac
Andrew 2009年

还需要注意的是改变包装内容物(如Info.plist中)可能导致代码签名的问题:bridge.grumpy-troll.org/2011/01/...
drevicko

2

将应用程序包装在AppleScript启动器中。

步骤如下。

  1. 创建具有以下内容的AppleScript,并将其保存为应用程序(在本示例中,其名为“ 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. 在Finder中转到该应用,右键单击它,显示包装内容。

  3. 将您的应用程序放在包内容的根目录中。(在此示例中为“ Firefox 3.app”)

    结果: /应用/火狐3 launcher.app/Firefox 3.app

  4. 您现在可以打开应用程序启动器。

笔记:

  • 包装的应用程序的自动更新在大多数情况下应该可以工作。
  • 应该可以将对启动器的任何拖放操作自动重定向到包装的应用程序(使用更多脚本)。
  • 打包的应用程序启动后,启动器将自动退出。
  • 此方法的优点是几乎没有直接打开包装的应用程序的风险。

1

为什么不使用:

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

很简单,但是有效。


2
如果这样做,终端将打开。
MJeffryes,2009年

0

open命令具有一个可选--args参数,该参数的值将作为参数传递给打开的应用程序。例如:

open /Applications/TextEdit.app --args example.txt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.