Mac OS uygulamalarını kısaca komut satırından başlatmak


22

Komut satırında oldukça fazla çalışma yapıyorum ve kendimi formun birçok diğer adını tanımlarken buluyorum:

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

Yürütülebilir "foo" istemek için otomatik olarak çalıştırılabilir /Applications/Foo.app/Contents/MacOS/Foo kullanacak şekilde sihir eklemenin bir yolu var mı? Bu OS X 10.6'da.

(Yapabileceğimin farkındayım open foo.pdf, ancak Skim varsayılan PDF okuyucusu değil ve genel bir çözüm istiyorum - bazı durumlarda söz konusu uygulamayı dosyanın varsayılan işleyicisi olarak ayarlamak uygun değildir.)


22
Şunları yapabilirsiniz open -a Skim foo.pdf.

1
@mankoff: nice, Uygulamalar dizinden bir uygulama istediğinizi belirtmek için -a'yı kullanabileceğinizi unuttum. Bunu bir cevap olarak değiştirmelisiniz :)
Robert S Ciaccio

@Reid: sorunuzu, yazmak istediğiniz bir örnek komut satırı içerecek şekilde düzenleyebilir misiniz?
Robert S Ciaccio

@ mankoff, tablonun tamamlandığından emin olmak veya uzatmak için takma adlara ihtiyaç duyduğu anlamına geliyor
Robert S Ciaccio

@Sözümü ile ilgili herhangi bir sorun var mı?

Yanıtlar:


10

Sonunda anladım: Bunu da ekle .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()

Şimdi aşağıdaki işler:

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

Reid tarafından düzenleyin:

Yukarıdakileri, diğer adlar yerine sarmalayıcı komut dosyaları yapan bir Python komut dosyası olarak uyguladım. Yoluna koyman gerekecek ~/bin/mankoffmagic. Paketleyicilerin otomatik olarak güncellenmesini istiyorsanız, cron veya somesuch'ten düzenli olarak çalıştırın.

#!/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()

"Grep -v iWork" oradadır, çünkü "iWork '09" daki kesme işareti her şeyi mahvetti. Uygulamaları başka bir yerde saklarsanız (~ / local / Applications) sadece lskomuta ekleyin , bu da işe yarayacaktır.

güzel bir. Dinamik olmasını seviyorum, böylece eski takma adları temizleme gibi herhangi bir bakım sorunuyla karşılaşmazsınız.
Robert S Ciaccio,

@Mankoff teşekkürler! Harika kokuyor - bir kez test ettim ve işe yaradıysa kabul edilen cevabı işaretleyeceğim. Çok takdir.
Reid

Tamam, bu işe yarıyor. Kesme işareti olan uygulamalar üzerinde (ve adında muhtemelen diğer komik karakterler) kırılıyor. Çözümünüzü karıştırdım ve Python'da benzer bir şey yaptım, başka bir cevapta yazacağım - yine de doğru görgü kuralları olmasa da, cevabınıza (veya her neyse) eklemekten mutluluk duyuyorum.
Reid

8

Fantezi bir şeye ihtiyacın yok, zaten cevabını aldın. Deneyin:

open /Applications/Foo.app bar.pdf

düzende

Aşağıdaki yorumların ışığında, cevabımın hala göreceli olarak benzer olacağını düşünüyorum ... Açık bırakan /Applications, zorlayan , çağrı yapan /usr/bin/open $appName.app $args, popd yapan ve geri dönen bir işlev yaparım .

Ben kabuk komut dosyası emmek ama aşağıdaki gibi bir şey özel durumlarda kapsar ve hemen hemen sağlanan elma ile aynı sözdizimini kullanarak tutar. Çevremi olabildiğince temiz tutmayı seviyorum.

Sözdiziminin uzaydan geldiğinden eminim:

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
}

ikinci düzenlemede

@ mankoff'un asıl soru hakkındaki yorumuna bakarak, yukarıdaki işlevdeki öğelerin çoğu muhtemelen kullanabileceğinizden beri zaman kaybı olabilir open -a $appName. Bu yüzden mankoff muhtemelen en kolay çözüme sahiptir ve yorumunu bir cevap olarak değiştirmelidir;)


@Reid'nin tüm takma adları elle oluşturmadan daha kısa bir yol istediğini düşünüyorum.

Fakat .app paketinde 'open' kullanıyorsa, unix çalıştırılabilirine bir takma ad oluşturmak zorunda değildir. Doğrudan takma komuttan bir uygulamayı başlatmanın tek yolunun MacOS dizinine girerek ve bir uygulamanın içinde 'gerçek' çalıştırılabilir dosyayı çalıştırmak olduğunu düşündüğü için takma ad oluşturduğu izlenimini edindim. Bu durumda, bir takma ad en azından uygulamayı başlatmak için gerek duyacağınız üç ekstra dizin yapısı seviyesini yazarak tasarruf sağlar. Belki de sorusunu yanlış anlıyorum.
Robert S Ciaccio

@calevara, teşekkürler - @mankoff haklı; uzunluk hakkında.
Reid

3
Bu düzenleme işlevinin kötüye kullanılmasıdır. Daha sonra ikinci bir cevap önermek isterseniz, sadece bunu yapın. Özgün cevabınızı düzenlemeyin, yeni oyunuza aldığı oyları göz önünde bulundurun.
Jeff Swensen

1
Kabul etmiyorum ... cevap hala oldukça benzer, çünkü aynı sözdizimini kullanıyor olacaktı. Sadece bu değil, oy kullananlar yeni cevabı beğenmiyorlarsa, cevabı değiştirildiği için oylarını değiştirebilirler. İşte bu yüzden düzenlemelerden sonra oyunuzu değiştirebilirsiniz. Bu yüzden "düzenleme" yi koyu olarak yazdım.
Robert S Ciaccio 24:10

4

Aklıma gelen iki çözüm var:

Daha kolay yol - Info.plistHer .app Contentsdizinindeki dosyayı kullanarak CFBundleExecutable anahtarlarının değerinin bir dizinini oluşturun. Ardından, bir yürütülebilir dosya adı ve iletmek istediğiniz bağımsız değişkenlerle birlikte bir komut dosyası (perl, python, her neyse) çağıran kısa bir diğer ad ekleyin.

Dizininiz, yürütülebilir dosya adlarının ve bu çalıştırılabilir dosyaların yollarının çiftleri olur. Bu durumu güncel tutmak için düzenli bir zamanlanmış komut dosyası yazmanız gerekir.

Sonunda arayabilirsin:

f foo file.txt

buradaki f, dizininizi bir yürütülebilir dosya için denetleyen bir komut dosyasının diğer adıdır foo.

Sonuçta, istediğiniz işlevselliği elde etmek için çok fazla iş değil.

En zor yol - Kabuğunun command_not_foundhatalarını gidermek için uzatın . Temel olarak method_missing, kullandığınız kabuk içinde Ruby tarzı bir işlevsellik uygulayacaksınız . Ne zaman command_not_foundatıldı, senin yöntem yüklü Uygulamalarının çalıştırılabilir isimlerini kontrol ederim.


2

Kurtarma Uygulaması:

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

Uygulamanın adını, başlatmak istediğiniz uygulamayla değiştirin ve işlemi tamamlayın. Elbette gerekirse bir kabuk işlevi yapabilirsiniz:

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

ve bu şekilde kullanın:

f iTunes

El yazmasından nefret ediyorum ama bazen işe yarar ve komut satırındaki bir adı basitçe isimlendirmenin tek yolunun olduğuna inanıyorum. Geriye kalan her şey tam yol gerektirecektir.


Sekme tamamlamayı desteklemiyor. Tam olarak uygulama adlarını hatırlamak gerektirir. Apple Script'in neden gerekli olduğunu anlamayın (özellikle de ondan nefret ediyorsanız), eğer kabuk komut dosyası yazabiliyorsa.

1
Open-a'nın bir dosya ismi olmadan argüman olarak kullanılabileceğini asla anlamadım. Ve NextStep'ten beri bazen 90'ların başlarında açık kullanıyorum! Lütfen bunu bir cevap olarak gönderin ki oylayabileyim. Öyleyse evet, doğru cevabı 'open -a <uygulama adı>' kullanmaktır
eric
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.