我在命令行中做了很多工作,我发现自己定义了许多形式的别名:

alias skim='/Applications/Skim.app/Contents/MacOS/Skim'

是否有一种方法可以添加魔法,以便要求可执行的“ foo”自动使用可执行/applications/foo.app/contents/macos/foo? 这是在OS X 10.6上。

(我知道我可以做 open foo.pdf, ,但是SKIM不是默认的PDF读取器,我希望有一个通用解决方案 - 在某些情况下,将相关应用程序设置为文件的默认处理程序是不合适的。

有帮助吗?

解决方案

最后我明白了:将其添加到您 .bash_profile

function foomagick() {
    rm -f ~/.foomagick.tmp
    ls /Applications/ | grep "\.app" | grep -v iWork | while read APP; do
        # clean it up                                                           
        a=`echo $APP | sed s/\ //g`;
        a=`echo $a | sed s/\'//g`;
        echo alias ${a%.*}="'open -a \"${APP%.*}\"'" >> ~/.foomagick.tmp
    done
    source ~/.foomagick.tmp
    rm ~/.foomagick.tmp  
}
foomagick()

现在以下工作:

Skim # open Skim.app
Skim foo.pdf
FireFox http://google.com
FireFox google.com # ERROR. Looks for local file.

REID编辑:

我将上述实现为Python脚本,该脚本制作包装脚本而不是别名。你需要放 ~/bin/mankoffmagic 在你的道路上。如果您希望包装器自动更新,请定期从Cron或Somesuch运行。

#!/usr/bin/python
#
# This script automagically updates a set of wrapper shell scripts in
# ~/bin/mankoffmagic which call Mac apps installed in /Applications.
#
# Inspired by mankoff's shell alias posted on apple.stackexchange.com; see:
# http://apple.stackexchange.com/questions/4240/concisely-starting-mac-os-apps-from-the-command-line/4257#4257
#
# Notes/Bugs:
#
# 1. Does not follow symlinks (aliases?)
#
# 2. Assumes that application names do not contain double-quotes.
#
# 3. Not very smart about finding the actual binary (it guesses). This is
# wrong sometimes, e.g. Firefox. Probably a deeper understanding of the app
# package structure would fix this.

import copy
import glob
import os
import os.path
import re

BINDIR = os.path.expandvars("$HOME/bin/mankoffmagic")
APP_RE = re.compile(r'(.*)\.app$')
STRIP_RE = re.compile(r'[\W_]+')

def main():
   # We aggressively delete everything already in BINDIR, to save the trouble
   # of analyzing what should stay
   for f in glob.glob("%s/*" % BINDIR):
      os.unlink(f)

   # Walk /Applications and create a wrapper shell script for each .app dir
   for (root, dirs, files) in os.walk("/Applications"):
      dirs_real = copy.copy(dirs)  # so we can manipulate dirs while looping
      for d in dirs_real:
         #print "checking %s" % os.path.join(root, d)
         m = APP_RE.search(d)
         if (m is not None):
            #print "Found " + m.group()
            dirs.remove(d)  # no need to recurse into app
            create_script(root, d, m.group(1))

def create_script(path, appdir, appname):
   # remove non-alphanumerics and downcase it
   wrapper = STRIP_RE.sub('', appname).lower()
   wrapper = os.path.join(BINDIR, wrapper)
   fp = open(wrapper, "w")
   # Twiddle the comments in the script depending on whether you want to
   # invoke the binary or use "open" -- the former lets you use any
   # command-line args, while the latter is more Mac-like (app puts itself in
   # the front, etc.)
   fp.write("""
#!/bin/sh
exec "%s/%s/Contents/MacOS/%s" "$@"
#open -a "%s" "$@"
""" % (path, appdir, appname, appname))
   fp.close()
   os.chmod(wrapper, 0700)


if (__name__ == "__main__"):
   main()

其他提示

您不需要任何花哨的东西,您已经有了答案。尝试:

open /Applications/Foo.app bar.pdf

编辑

鉴于下面的评论,我认为我的答案仍然相对较相似...我会做出覆盖的功能,然后推动 /Applications, ,电话 /usr/bin/open $appName.app $args, ,做一个流行音乐并返回。

我很吮吸贝壳脚本,但是下面的东西涵盖了特殊案例,并使您使用与苹果开放的语法几乎相同的语法。我喜欢保持环境尽可能清洁。

我确定语法来自外太空:

function open($appName, $args)
{
    #if we are calling open without a path like /Applications/TextEdit.app AND
    #    $appName ends in '.app'
    if (!hasParent($appName) && isApp($appName))
    {
        pushd /Applications
        /usr/bin/open ${appName}.app $args &
        popd
        return
    }
    #otherwise, use open as normal
    /usr/bin/open $appName $args
    return
}

在第二次编辑中

查看 @Mankoff对原始问题的评论,上述功能中的大多数内容可能会浪费时间,因为您可以使用 open -a $appName. 。因此,曼科夫可能有最简单的解决方案,应该将他的评论更改为答案;)

我可以想到两种解决方案:

更容易的方法 - 使用 Info.plist 每个.App中的文件 Contents 目录,为键CFBundleExecutable创建值的索引。然后添加一个简短的别名,该别名称为脚本(perl,python等),并使用可执行文件的名称和您要通过的参数。

您的索引将是对这些可执行文件的一对可执行的名称和路径。您必须编写一个经常出现的计划脚本以保持更新。

您最终能够致电:

f foo file.txt

其中f是对脚本的别名,该脚本检查您的索引的可执行文件 foo.

总而言之,没有很多工作来获得您想要的功能。

较难的方式 - 扩展外壳以补充其处理 command_not_found 错误。本质上,您将实施红宝石风格 method_missing 您使用的任何外壳中的功能。什么时候 command_not_found 被扔了,您的方法将检查已安装应用程序的可执行名称。

营救的苹果记录:

osascript -e 'tell application "iTunes"' -e "activate" -e 'end tell'

用您要启动并完成的应用程序替换应用程序的名称。您当然可以在需要时使其成为外壳功能:

function f() {
    osascript <<EOF
tell application "$1"
  activate
end tell
EOF
}

并以这种方式使用:

f iTunes

我讨厌AppleScript,但有时很有用,我相信仅在命令行上使用名称来解决应用程序的唯一方法。其他一切都需要一条完整的道路。

许可以下: CC-BY-SA归因
不隶属于 apple.stackexchange
scroll top