Question

Je fais un montant équitable du travail dans la ligne de commande, et je me trouve la définition d'un grand nombre d'alias de la forme:

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

Est-il possible d'ajouter la magie telle que demander de "foo" exécutable utilise automatiquement /Applications/Foo.app/Contents/MacOS/Foo exécutable? Il est sur OS X 10.6.

(Je suis conscient que je pouvais faire open foo.pdf, mais Skim est pas le lecteur de PDF par défaut, et je voudrais une solution générale - dans certains cas, il est approprié de ne pas mettre l'application en question comme gestionnaire par défaut le fichier.)

Était-ce utile?

La solution

Enfin, je l'ai: Ajoutez ceci à votre .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()

Maintenant les travaux suivants:

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

Modifier par Reid:

Je mis en œuvre ci-dessus comme un script Python qui fait wrapper scripts au lieu d'alias. Vous aurez besoin de mettre ~/bin/mankoffmagic dans votre chemin. Si vous voulez que les emballages soient mis à jour automatiquement, exécutez régulièrement ou 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()

Autres conseils

Vous ne fancy rien pas besoin, vous avez déjà la réponse. Essayez:

open /Applications/Foo.app bar.pdf

sur modifier

À la lumière des commentaires ci-dessous, je pense que ma réponse serait encore relativement similaire ... Je ferais une fonction qui outrepasse ouvrir, fait un pushd à /Applications, appelle /usr/bin/open $appName.app $args, fait un popd et retourne.

Je suce au script shell, mais quelque chose comme ci-dessous, qui couvre des cas particuliers et vous permet de rester en utilisant à peu près la même syntaxe que la pomme prévue ouverte. Je tiens à garder mon environnement aussi propre que possible.

Je suis sûr que la syntaxe est de l'espace:

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
}

sur la deuxième édition

recherche @ commentaire de Mankoff sur la question d'origine, la plupart des choses dans la fonction ci-dessus serait probablement une perte de temps puisque vous pouvez simplement utiliser open -a $appName. Donc Mankoff a sans doute la solution la plus simple et devrait changer son commentaire à une réponse;)

Il y a deux solutions que je peux penser à:

La façon plus simple - Utilisation du fichier Info.plist dans chaque .app répertoire Contents, créer un index de la valeur pour les touches CFBundleExecutable. Ensuite, ajoutez un alias court qui appelle un script (perl, python, peu importe) avec le nom d'un exécutable et les arguments que vous souhaitez passer.

Votre index serait paires de noms exécutables et les chemins de ces exécutables. Il faudrait écrire un script récurrent prévu pour maintenir cette mise à jour.

Vous finirais pouvoir appeler:

f foo file.txt

où f est un alias à un script qui vérifie l'index pour un exécutable foo nommé.

Dans l'ensemble, pas beaucoup de travail pour obtenir la fonctionnalité que vous souhaitez.

La façon plus difficile - Prolongez votre shell pour compléter le traitement de son erreur de command_not_found. Essentiellement vous mettre en œuvre une fonctionnalité de method_missing de style Ruby au sein du shell que vous utilisez. Lorsque command_not_found a été jeté, votre méthode vérifiait les noms exécutables de vos applications installées.

AppleScript à la rescousse:

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

Remplacez le nom de l'application avec l'application que vous souhaitez démarrer et vous avez terminé. Vous pouvez bien sûr faire une fonction shell si nécessaire:

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

et de l'utiliser de cette façon:

f iTunes

Je déteste AppleScript, mais il est parfois utile, et je crois que la seule façon de répondre à une demande simplement par son nom sur la ligne de commande. Tout le reste, il faudra un chemin complet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à apple.stackexchange
scroll top