Ich arbeite ziemlich viel in der Befehlszeile und ertappe mich dabei, wie ich viele Aliase des Formulars definiere:
alias skim='/Applications/Skim.app/Contents/MacOS/Skim'
Gibt es eine Möglichkeit, Magie hinzuzufügen, sodass die Abfrage nach der ausführbaren Datei "foo" automatisch die ausführbare Datei /Applications/Foo.app/Contents/MacOS/Foo verwendet? Dies ist unter OS X 10.6.
(Mir ist bewusst, dass ich das tun könnte open foo.pdf
, aber Skim ist nicht der Standard-PDF-Reader, und ich hätte gerne eine allgemeine Lösung - in einigen Fällen ist es nicht angebracht, die betreffende Anwendung als Standard-Handler für die Datei festzulegen.)
Endlich habe ich es verstanden: Fügen Sie dies zu Ihrer hinzu.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()
Nun folgende Arbeit:
Skim # open Skim.app
Skim foo.pdf
FireFox http://google.com
FireFox google.com # ERROR. Looks for local file.
Bearbeiten von Reid:
Ich habe das Obige als Python-Skript implementiert, das Wrapper-Skripte anstelle von Aliasen erstellt. Sie müssen ~/bin/mankoffmagic
Ihren Pfad eingeben. Wenn Sie möchten, dass die Wrapper automatisch aktualisiert werden, führen Sie sie regelmäßig von cron oder so aus.
#!/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()
ls
Befehl hinzu, und dies wird auch dort funktionieren.Sie brauchen nichts Ausgefallenes, Sie haben bereits die Antwort. Versuchen:
open /Applications/Foo.app bar.pdf
In Anbetracht der folgenden Kommentare denke ich, dass meine Antwort immer noch relativ ähnlich wäre ... Ich würde eine Funktion erstellen, die open überschreibt, ein pushd zu macht /Applications
, aufruft /usr/bin/open $appName.app $args
, ein popd macht und zurückkehrt.
Ich sauge an Shell-Scripting, aber etwas wie unten, das Sonderfälle abdeckt und Sie dazu bringt, so ziemlich die gleiche Syntax zu verwenden, die Apple für open bereitgestellt hat. Ich halte meine Umgebung gerne so sauber wie möglich.
Ich bin mir sicher, dass die Syntax aus dem Weltraum stammt:
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
}
Wenn Sie den Kommentar von @mankoff zur ursprünglichen Frage betrachten, wäre das meiste in der obigen Funktion wahrscheinlich Zeitverschwendung, da Sie einfach verwenden könnten open -a $appName
. Mankoff hat also wahrscheinlich die einfachste Lösung und sollte seinen Kommentar in eine Antwort ändern;)
$ foo bar.pdf
?Da fallen mir zwei Lösungen ein:
Der einfachere Weg – Erstellen Sie mithilfe der Info.plist
Datei in jedem .app Contents
-Verzeichnis einen Index des Werts für die Schlüssel CFBundleExecutable. Fügen Sie dann einen kurzen Alias hinzu, der ein Skript (Perl, Python, was auch immer) mit dem Namen einer ausführbaren Datei und den Argumenten aufruft, die Sie übergeben möchten.
Ihr Index besteht aus Paaren ausführbarer Namen und Pfaden zu diesen ausführbaren Dateien. Sie müssten ein wiederkehrendes geplantes Skript schreiben, um dies auf dem neuesten Stand zu halten.
Sie könnten am Ende anrufen:
f foo file.txt
wobei f ein Alias für ein Skript ist, das Ihren Index auf eine ausführbare Datei mit dem Namen überprüft foo
.
Alles in allem nicht viel Arbeit, um die gewünschte Funktionalität zu erhalten.
Der schwierigere Weg - Erweitern Sie Ihre Shell, um die command_not_found
Fehlerbehandlung zu ergänzen. Im Wesentlichen würden Sie eine method_missing
Funktionalität im Ruby-Stil in der von Ihnen verwendeten Shell implementieren. Wenn command_not_found
ausgelöst wurde, würde Ihre Methode die ausführbaren Namen Ihrer installierten Anwendungen überprüfen.
Applescript zur Rettung:
osascript -e 'tell application "iTunes"' -e "activate" -e 'end tell'
Ersetzen Sie den Namen der Anwendung durch die Anwendung, die Sie starten möchten, und Sie sind fertig. Sie können es natürlich bei Bedarf zu einer Shell-Funktion machen:
function f() {
osascript <<EOF
tell application "$1"
activate
end tell
EOF
}
und benutze es so:
f iTunes
Ich hasse Applescript, aber es ist manchmal nützlich, und ich glaube, die einzige Möglichkeit, eine Anwendung einfach über den Namen auf der Befehlszeile anzusprechen. Alles andere erfordert einen vollständigen Pfad.
Benutzer588
open -a Skim foo.pdf
.Robert S Ciaccio
Robert S Ciaccio
Robert S Ciaccio
Benutzer588